The Retry Problem
Network failures happen. When a client sends a request and does not get a response, it does not know if the request failed or the response was lost. The natural reaction is to retry. But if the original request succeeded, a retry might create duplicate resources or charge a customer twice. Idempotency solves this.
What Idempotency Means
An idempotent operation produces the same result regardless of how many times it is executed. GET, PUT, and DELETE are naturally idempotent in REST. POST is not — and that is where most problems occur. The solution: give clients a way to make POST idempotent.
Idempotency Keys
The pattern I use most: clients generate a unique idempotency key (UUID) and send it with each POST request. The server stores the key with the response. If the same key arrives again, return the cached response without re-executing the operation.
async function handlePayment(req, res) {
const { idempotencyKey, amount, customerId } = req.body;
// Check if we already processed this request
const cached = await redis.get(`idem:${idempotencyKey}`);
if (cached) {
return res.status(200).json(JSON.parse(cached));
}
// Process the payment
const result = await paymentGateway.charge(amount, customerId);
// Cache the response with TTL
await redis.set(`idem:${idempotencyKey}`, JSON.stringify(result), { EX: 86400 });
return res.status(200).json(result);
}
Storage Considerations
Idempotency keys need durable storage. Redis works for most cases with proper TTL. For financial systems, store keys in the primary database with the transaction record. The key must be unique per client — include the client ID in the cache key to prevent collisions.
Key Takeaways
- Make every POST endpoint idempotent using client-provided keys
- Store the full response, not just a processed flag — retries expect the same response
- Set appropriate TTLs — 24 hours covers most retry scenarios
- Document idempotency requirements clearly in your API docs
- Test retry behavior in your integration test suite
Senior Software Engineer specializing in cloud architecture, real-time systems, and enterprise-scale applications.