In distributed systems, one truth stands above all:
π Failures will happen. Retries are inevitable.
But hereβs the real challenge:
What happens when the same request is executed multiple times?
- Duplicate payments
- Multiple orders
- Inconsistent state
This is where idempotency becomes a critical concept in API design.
π§ What is Idempotency?
An operation is idempotent if:
Performing it multiple times produces the same result as performing it once.
π§Ύ Simple Example
DELETE /users/123
- First call β deletes user
- Second call β user already deleted
π Result is the same: user does not exist
β This is idempotent
β Non-Idempotent Example
POST /orders
- First call β creates order #1001
- Second call β creates order #1002
π Duplicate orders = big problem
π₯ Why Idempotency Matters in Real Systems
In production, retries happen due to:
- Network timeouts
- Service failures
- Client retries
- Load balancer retries
Tools like NGINX or AWS Elastic Load Balancer may retry requests automatically.
π Without idempotency, retries can corrupt your data.
β οΈ Real-World Failures
πΈ Duplicate Payments
A payment request is retried:
POST /payments
π Without idempotency:
- Customer gets charged twice
π Duplicate Orders
User clicks βBuyβ multiple times:
π System creates multiple orders
π Trading Systems
In a trading platform:
POST /execute-trade
π Duplicate execution = real financial loss
π§© HTTP Methods and Idempotency
| Method | Idempotent? | Why |
|---|---|---|
| GET | β Yes | Read-only |
| PUT | β Yes | Replaces resource |
| DELETE | β Yes | Removes resource |
| POST | β No | Creates new resource |
| PATCH | β Usually | Partial updates |
π The biggest challenge is making POST operations idempotent.
ποΈ How to Design Idempotent APIs
π 1. Idempotency Keys (Most Important Pattern)
Client sends a unique key:
POST /payments
Idempotency-Key: abc123
π How It Works
- Server receives request with key
- Stores the result (DB or cache)
- If same key is reused:
- Return same response
- Do NOT reprocess
π§ͺ Example Flow
Client β POST /payments (key=abc123)
β Payment processed
Client retries β same key
β Server returns cached response
β No duplicate payment
β Safe retries
π§° Implementation Strategies
1. Database Constraint
- Unique key per request
- Reject duplicates
β Simple
β Doesnβt return original response
2. Cache-Based (Best Practice)
Use Redis:
- Store key + response
- Add TTL (e.g., 24 hours)
β Fast
β Scalable
3. Hash-Based Requests
- Generate hash from request body
- Use as idempotency key
β Automatic
β Risk of collisions (rare but possible)
βοΈ Real Backend Example
π³ Payment API
POST /payments
Idempotency-Key: user123-transaction456
Server logic:
- Check if key exists
- If not:
- Process payment
- Store response
- If exists:
- Return stored response
π Internal Microservices
Even internal calls need idempotency:
Order Service β Payment Service
π If retry happens, system remains consistent.
β οΈ Common Mistakes
β Ignoring Idempotency in Critical Flows
- Payments
- Orders
- Financial transactions
π These MUST be idempotent.
β Storing Only the Key
π You must store:
- Request result
- Status
- Response
β Infinite Storage
π Always use TTL:
- Prevent memory leaks
- Clean old keys
π§ Design Insight
Idempotency is not just a backend concernβitβs a system-wide guarantee.
π It works together with:
- Retries
- Message queues
- Event-driven systems
In tools like Apache Kafka, idempotency is essential to avoid duplicate event processing.
π Advanced Pattern: Idempotent Consumers
In event-driven systems:
- Messages may be delivered multiple times
- Consumers must handle duplicates
π Solution:
- Track processed message IDs
- Ignore duplicates
π‘ Final Thoughts
Idempotency is one of those concepts that separates mid-level engineers from senior engineers.
Without it:
- Systems break under retries
- Data becomes inconsistent
With it:
- Systems become safe, predictable, and resilient
π If your system handles money, orders, or critical data:
Idempotency is not optionalβitβs mandatory.