Glossary

Idempotent

Idempotent describes an operation whose intended effect on the server is the same whether it runs once or many times, which is what makes it safe to retry after a timeout. In HTTP, RFC 9110 section 9.2.2 defines it for request methods: PUT, DELETE and all safe methods are idempotent, while POST is not.

How it works

The word comes from mathematics, where a function is idempotent if applying it twice gives the same result as applying it once. In an API the test is about server state, not about the response you receive.

  • Idempotent methods: GET, HEAD, OPTIONS, TRACE, PUT and DELETE.
  • Not idempotent: POST. PATCH is neither safe nor idempotent by definition (RFC 5789), though a particular patch can be written to be idempotent.
  • Same effect, different response: the second DELETE of the same URL may return 404 instead of 204, and the second PUT may return 200 instead of 201. The resource ends up in the same state, so both are idempotent.
  • Side effects are allowed: RFC 9110 lets a server log every request separately. Only the effect the client asked for must not accumulate.

The rule exists because of retries. If a connection drops before the response arrives, the client cannot know whether the server acted. For idempotent methods the client may safely send the request again. A client should not automatically retry a non-idempotent request, and a proxy must not.

For POST, APIs commonly add an idempotency key: a unique value the client sends and the server remembers. The transcript below shows a server that does exactly that, compared with plain PUT, DELETE and POST.

PUT, 1st                   PUT    /orders/a1  201 {"id":"a1"}
PUT, 2nd (same)            PUT    /orders/a1  200 {"id":"a1"}
DELETE, 1st                DELETE /orders/a1  204 (empty)
DELETE, 2nd                DELETE /orders/a1  404 {"error":"not found"}
POST, 1st                  POST   /orders     201 {"id":"o1"}
POST, retry                POST   /orders     201 {"id":"o2"}
POST + key, 1st            POST   /orders     201 {"id":"o3"}
POST + key, retry          POST   /orders     201 {"id":"o3"}
orders stored: o1,o2,o3

The plain POST retry created a second order, o2. The keyed retry returned the stored result for o3 and created nothing new.

Is POST idempotent?

No, POST is not idempotent in the HTTP specification, and sending the same POST twice can create two records. A client should only retry it automatically when it knows the request is safe for that resource, or can detect that the first attempt never took effect. An idempotency key lets a server make a specific POST endpoint behave idempotently.

What is the difference between idempotent and safe?

A safe method asks for no state change at all, while an idempotent method may change state but only once. Every safe method is idempotent, but PUT and DELETE are idempotent without being safe. GET, HEAD, OPTIONS and TRACE are the safe ones.

Common pitfalls

  • Trusting the method name: the server decides the behavior. A PUT /counter handler that does count += 1 is not idempotent, and retries will corrupt it. PUT must replace state with what the body says.
  • Treating a repeat DELETE 404 as failure: after a lost response, the retry may return 404 even though the delete worked. Clients should accept it as success.
  • Reusing a key with a different body: the original 2020 IETF Idempotency-Key draft suggested answering 422 when a key is reused with a different payload. The draft expired without becoming an RFC, so check each API's own rules.
  • Race on duplicate requests: two copies arriving together can both pass a "key not seen" check. Store the key atomically, and reject the duplicate (many APIs answer 409 Conflict) while the first request is still running.
  • Keys that never expire or collide: use a random value such as a UUID, and set a retention window so the table does not grow forever.

Related terms

  • HTTP — defines which methods are idempotent
  • REST — API style that relies on these method semantics
  • UUID — a common format for idempotency keys
  • Webhook — HTTP callbacks whose handlers benefit from idempotent processing

See also