Understanding Idempotent HTTP Methods
Deep dive into idempotency in HTTP — which methods are idempotent, why it matters for reliability, and how to handle non-idempotent methods safely.
Detailed Explanation
What Is Idempotency?
An HTTP method is idempotent if making the same request one or more times produces the same server state. The response may differ (e.g., the first DELETE returns 200, the second returns 404), but the resource state remains the same.
Idempotency Matrix
| Method | Idempotent | Explanation |
|---|---|---|
| GET | Yes | Reading data does not change state |
| HEAD | Yes | Same as GET without the body |
| PUT | Yes | Replacing a resource with the same data yields the same result |
| DELETE | Yes | Deleting an already-deleted resource is a no-op |
| OPTIONS | Yes | Describing capabilities does not change state |
| TRACE | Yes | Echoing a request does not change state |
| POST | No | Each call may create a new resource |
| PATCH | No | Partial updates may have cumulative effects |
| CONNECT | No | Each tunnel establishment is a new connection |
Why Idempotency Matters
- Network retries — If a request times out, idempotent methods can be safely retried without side effects
- Load balancers — Can retry failed requests on another server
- Client reliability — Mobile apps and SPAs can retry on poor connections
- Caching — Idempotent methods are candidates for response caching
Making POST Idempotent with Idempotency Keys
Many payment APIs (Stripe, PayPal) use an Idempotency-Key header:
POST /api/payments HTTP/1.1
Content-Type: application/json
Idempotency-Key: unique-uuid-per-request
{ "amount": 1000, "currency": "USD" }
If the same key is sent again, the server returns the original response without processing the payment twice.
Idempotency vs Safety
All safe methods are idempotent, but not all idempotent methods are safe. PUT and DELETE change server state (not safe) but produce the same outcome when repeated (idempotent).
Use Case
A mobile app sends a PUT request to update a user profile. The network drops after the request is sent but before the response arrives. The app retries the PUT, and because PUT is idempotent, the profile is updated once, not corrupted by a double-write.