Designing Idempotency Patterns

1. Understanding Idempotency Concepts

TermMeaning
Idempotentf(f(x)) == f(x); safe to retry
Naturally idempotentPUT /resource/123, DELETE
Made idempotentPOST + idempotency key
Effectively-onceAt-least-once delivery + idempotent processing

2. Designing Idempotent APIs

HTTP VerbIdempotent?Notes
GETYesSafe + idempotent
PUTYesReplace
DELETEYesSubsequent returns 404 or 204
POSTNo (default)Add Idempotency-Key header
PATCHDependsIdempotent if absolute, not if delta

3. Designing Request Deduplication

Example: Idempotency key (Stripe-style)

POST /v1/charges
Idempotency-Key: 9b2a3c1e-7d22-4d4a-8d2e-...

Server:
  if (cache.has(key)) return cache.get(key); // same response
  result = doWork(req);
  cache.put(key, result, ttl=24h);
  return result;
ElementDetail
Key sourceClient-generated UUID per logical request
StorageRedis or DB with TTL (24h typical)
ScopePer endpoint + tenant
Concurrent same-keyLock or 409 Conflict

4. Implementing Idempotency in Message Processing

TechniqueDetail
Dedup by message IDTrack processed IDs in store
Idempotent opUPSERT, conditional update
Outbox + inboxInbox table dedups before applying
Kafka idempotent producerenable.idempotence=true

5. Designing At-Least-Once with Idempotency

ComponentRole
ProducerRetry until ack
ConsumerProcess + dedup before commit offset
Effective semanticsExactly-once outcome

6. Designing Exactly-Once Semantics

SystemMechanism
Kafka EOSIdempotent producer + transactions
Flink checkpointsTwo-phase commit sink
DB outboxWrite event + state in same txn
PulsarDeduplication enabled at broker
Warning: True end-to-end exactly-once requires coordination at every hop. Most systems achieve "effectively once" via at-least-once + idempotency.

7. Designing Idempotent Database Operations

OpIdempotent Form
InsertINSERT ... ON CONFLICT DO NOTHING
UpsertINSERT ... ON CONFLICT DO UPDATE
IncrementUse idempotency key + processed table
DeleteWHERE id=? (re-run is no-op)

8. Designing Idempotent Payment Processing

Idempotent Payment Flow

  1. Client generates idempotency_key (UUID) per checkout attempt
  2. Server stores key + status (pending) in DB
  3. Call PSP with idempotency_key (PSPs like Stripe accept this)
  4. Persist PSP txn id; mark complete
  5. Retries with same key return stored response

9. Designing Retry-Safe Operations

PracticeDetail
Make ops idempotentDefault for safe retries
Exponential backoff + jitterAvoid thundering herd
Bounded retriesCap attempts; circuit breaker
Distinguish errorsRetry transient; surface permanent

10. Designing Idempotency Token Storage

StoreTrade-off
RedisFast; needs persistence/replication for safety
Relational DBDurable + transactional with the operation
DynamoDBConditional writes for atomic dedup
TTL24h–7d typical; longer for financial
Schema(key, request_hash, response, status, expires_at)