Updated 9 hours ago
You send a request. The network times out. Did the server process it?
You genuinely don't know. The request might have arrived and succeeded, with only the response lost. Or the request might have died in transit. The network doesn't tell you whether your request succeeded—it tells you whether it heard back. Those aren't the same thing.
Idempotency is how you handle this uncertainty.
What Idempotency Means
An HTTP method is idempotent if making the same request multiple times produces the same server-side effect as making it once.
DELETE is idempotent. Delete a resource once, it's gone. Delete it ten more times—it's still gone. The responses differ (first returns 204 No Content, subsequent return 404 Not Found), but the outcome is identical: the resource doesn't exist.
POST is typically not idempotent. Submit a form three times, you might create three resources. Charge a credit card three times, you bill the customer three times. Each request changes server state in a new way.
The Idempotent Methods
GET
Retrieving a resource doesn't change it. Request the same article a hundred times—the server state remains unchanged.
Caveat: Poorly designed APIs add side effects to GET—incrementing view counters, triggering actions, logging. This violates the HTTP specification and creates real problems when proxies, browsers, and load balancers retry GET requests expecting safety.
PUT
Updating a resource to a specific state is idempotent. Set an article's title to "Updated Title" once, it has that title. Set it again—it still has that title.
DELETE
Removing a resource is idempotent. The resource is gone after the first request. It's still gone after the tenth.
HEAD and OPTIONS
HEAD retrieves metadata without modifying anything. OPTIONS queries capabilities. Neither changes server state.
The Non-Idempotent Methods
POST
Each POST potentially creates new state:
This is the duplicate submission problem. Network timeouts, impatient users clicking "Submit" multiple times, automatic retries—all create unintended duplicates.
PATCH
PATCH can go either way, depending on the patch format.
Idempotent (setting absolute values):
Non-idempotent (relative changes):
JSON Merge Patch (RFC 7396) is idempotent. JSON Patch (RFC 6902) can be non-idempotent depending on the operations.
Why This Matters
Safe Retries
With idempotent methods, retry freely:
GET is idempotent. Retrying can't cause harm.
With POST, retrying is dangerous:
Load Balancers Retry Automatically
When a backend server times out, load balancers retry idempotent requests on another server:
They don't retry POST without special configuration. They know it's dangerous.
Browsers Protect Users
Refresh a page after submitting a form and you'll see:
Browsers know POST isn't idempotent. They warn before repeating.
Caching Works
Only idempotent methods can be safely cached. If a request changes server state, cached responses become lies.
GET responses cache by default. POST responses don't.
Making POST Idempotent
Since POST often needs retries, several patterns add idempotency:
Idempotency Keys
The client generates a unique key for each logical operation:
The server tracks keys. Same key twice? Return the original result:
Now retries are safe.
Client-Generated IDs
Let the client provide the ID:
PUT to a specific URL is idempotent. Order exists? Update it. Doesn't exist? Create it. Retry produces the same order.
Single-Use Tokens
Embed a token in the form:
Server validates and invalidates:
Duplicate submissions fail.
RESTful Design
Use methods according to their semantics:
Idempotent operations → PUT or DELETE
- Setting a resource to a specific state: PUT
- Removing a resource: DELETE
Non-idempotent operations → POST
- Creating with server-generated IDs: POST
- Actions that shouldn't repeat: POST
Idempotent. Setting status to "active" ten times leaves it active.
Not idempotent. Sending twice sends two messages.
Testing Idempotency
Verify your idempotent methods are actually idempotent:
Common Mistakes
GET with side effects: Don't modify state in GET handlers. Proxies and browsers will retry GET requests without asking.
Retrying POST blindly: Without idempotency keys or tokens, retries create duplicates.
Assuming PATCH is idempotent: It depends on the patch format. Increment operations aren't idempotent.
Frequently Asked Questions About HTTP Method Idempotency
Was this page helpful?