Idempotency Rules – HTTP, REST API, Idempotency Key & ETag
This post is a definition of terms for idempotency – including exam questions and tags.
In a Nutshell
Idempotency means: execute identical operations any number of times with the same result. Formally: f(f(x)) = f(x).
Compact Technical Description
Idempotency is a property of an operation, not an endpoint. It makes the result stable against repetitions. In HTTP, GET, HEAD, PUT, DELETE are idempotent by specification, POST is not, but can be made idempotent through Idempotency Key. In practice, idempotency means that repetitions do not create additional side effects (no duplicate orders, no multiple debits). Technically, this is achieved through deterministic state transitions, version checks with ETag, and deduplicating server logic. In distributed systems with at-least-once delivery, retries are normal; idempotency makes them safe.
Exam-Relevant Key Points
- Definition: f(f(x)) = f(x), idempotency as a property of the operation, not the path
- HTTP mapping: GET/HEAD safe and idempotent, PUT/DELETE idempotent, POST not idempotent
- POST idempotency with Idempotency Key, request hash, deduplicating store, deterministic responses
- Status and headers: 201 with Location on first attempt, repetition returns 200/201 consistently, 412 on If-Match conflict
- Traceability of side effects, logging of correlation ID, documented retry rules
- No sensitive data in errors, protection against replay through time-limited keys and signatures
- Fewer double bookings and support cases, robust integrations, clearly defined retry policy
- OpenAPI describes idempotency, error catalog, lifetime of Idempotency Keys, example responses
Core Components
- Formal definition and distinction from safe properties
- Method semantics in HTTP: GET, HEAD, PUT, PATCH, DELETE, POST
- Conditional requests with ETag, If-Match, If-None-Match
- Deduplication: storage, key to response, mapping with expiration
- Deterministic state transitions and conflict detection (409, 412)
- Idempotency Key generation: client generates stable key per business event
- Outbox/Inbox pattern for reliable side effects (events, payments)
- Retry strategy: exponential backoff, respect 429 and Retry-After
- Observability: correlation ID, trace idempotent operations
- Test procedures: retry tests, chaos tests, concurrency and race condition tests
Practical Example
// Idempotent POST for payment with Idempotency Key and ETag
POST payments
Headers: Content-Type: application/json, Idempotency-Key: pay-123-abc
Body: { orderId: 42, amount: 59.98, method: "card" }
Server logic:
if exists DedupeStore[key: pay-123-abc]:
return storedResponse
else:
if PaymentAlreadyConfirmed(orderId: 42):
resp = { id: "P9001", status: "confirmed" }, code: 200
else:
create Payment(id: "P9001", status: "confirmed")
resp = { id: "P9001", status: "confirmed" }, code: 201, headers: ETag: W/"r77"
DedupeStore.save(key: pay-123-abc -> resp with ttl: 24h)
return resp
Retry with same key:
Client sends POST again with Idempotency Key, server delivers same response, 201 on first attempt, 200 on later retries, never double debit.
Advantages and Disadvantages
Advantages
- Safe retries on network failures
- Protection against double bookings
- Clearer error modeling
- More robust integrations
- Better user experience
Disadvantages
- Additional storage and management overhead for deduplication
- More complex logic for side effects
- Precise definition of lifetime and semantics required
- Possible locks or conflicts with concurrency
Typical Exam Questions (with Short Answer)
- Difference between Safe and Idempotent? Safe = no server-side state change (GET), Idempotent = multiple executions without additional side effects (PUT/DELETE).
- Make POST operations idempotent? Idempotency Key per business event, deduplication store with key→response, deterministic logic, consistent status codes, limited validity.
- ETag and If-Match in idempotency? Protect against lost updates, update only at known version, otherwise 412 Precondition Failed.
- Is DELETE really idempotent? First DELETE returns 200/204, later DELETEs can return 204/404, system state remains the same (resource deleted).
- Typical status codes for idempotency/retries? 200/201/204 on success, 409 on business conflicts, 412 on precondition failed, 429 on limits + Retry-After, 5xx for temporary server errors.
- Define Idempotency Key lifetime? Business-wise until business event is final, technically as time window (e.g., 24h), documented in API.
- Risks without idempotency in distributed systems? Duplicate side effects (duplicate payments), inconsistent states, manual corrections, higher support costs.
- Idempotency with Event Sourcing and Outbox? Write event to Outbox (same transaction), reliably publish, consumer with Inbox for processed event IDs, idempotent handler.
Most Important Sources
- https://www.rfc-editor.org/rfc/rfc9110
- https://www.rfc-editor.org/rfc/rfc7807
- https://docs.stripe.com/idempotency