Theory
Idempotency in Distributed Systems
📋 Overview
Idempotency is the property of certain operations in mathematics and computer science whereby they can be applied multiple times without changing the result beyond the initial application. In system design, an idempotent API ensures that a retry (due to a timeout or network glitch) does not result in duplicate side effects, such as double-charging a customer or creating duplicate orders.
🏗️ Core Principles & Characteristics
- Definition:
f(x) = f(f(x)). The outcome of the first successful request is identical to all subsequent identical requests. - Safe vs. Idempotent:
- Safe Methods:
GET,HEAD(Should not change state). - Idempotent Methods:
PUT,DELETE(Repeated calls result in the same state). - Non-Idempotent Methods:
POST(Usually creates a new resource every time).
- Safe Methods:
- Idempotency Key: A unique identifier (typically a UUID) sent by the client that the server uses to recognize and deduplicate requests.
⚖️ Trade-offs: Pros & Cons
- Pros:
- Fault Tolerance: Clients can safely retry failed requests.
- Consistency: Prevents "double-action" bugs in distributed systems.
- Simplicity for Clients: Clients don't need complex logic to determine if a partial failure succeeded.
- Cons:
- Storage Overhead: Servers must store idempotency keys and their results for a period (e.g., 24 hours).
- Complexity: Implementing robust deduplication logic across distributed nodes requires distributed locking or atomic DB operations.
🌍 Real-World Implementation
- Payment Gateways (Stripe/PayPal): Mandate an
Idempotency-Keyheader for all transaction requests. - Database Level: Using
UPSERTorINSERT ... ON CONFLICTto ensure that re-running a migration or event-processing task is safe. - Message Queues: Ensuring that a consumer can process the same message multiple times (At-Least-Once delivery) without duplicating business logic.
💡 Interview "Gotchas" & Tips
- The "Two-Sided" Problem: What if the first request succeeded but the response was lost? The server has already changed the state. The second request must return the original success response, not an error.
- Distributed Lock: If two identical requests hit two different servers at the exact same millisecond, you need a distributed lock (e.g., Redis
SET NX) on the idempotency key. - Atomic State Transition: The best way to implement idempotency is to combine the "check-key" and "execute-business-logic" into a single database transaction.
📐 Suggested Architecture Primitives
- Idempotency Key Store: High-speed KV store (Redis) to track keys.
- Transactional DB: To ensure "process once" logic is atomic.
- Client-side UUID Generator: To create unique keys before the first attempt.
Canvas