Card 03/ 10

ConceptDifficulty: Beginner2 min

Safe and Idempotent Methods

A safe method changes nothing, and an idempotent one leaves the same state however many times it is sent.

HTTP defines two promises a method can make. A safe method asks for no change on the server, so it is a read. An idempotent method leaves the server in the same state whether it is sent once or many times, so a client may send it again after a timeout without making things worse. GET is both, PUT and DELETE are idempotent but not safe, and POST and PATCH promise neither.

Pressing a lift's call button is idempotent: pressing it five times still brings one lift. The comparison breaks in one place: the button is built so it cannot do otherwise, while an HTTP method only promises, and a server can break the promise.

Common methods against the two promises
MethodSafeIdempotent
GET, HEAD, OPTIONSYesYes
QUERYYesYes
PUTNoYes
DELETENoYes
POSTNoNo
PATCHNoNo, unless the patch only sets values

Safe means the client asks for no change. A server may still write a log line or bump a view counter; what matters is that the client did not request a change and cannot be blamed for one. Because of that, browsers prefetch links, crawlers follow them, and caches answer GETs from stored copies.

Idempotent is about the state, not the response. Sending DELETE /orders/42 twice may return 204 then 404, but the order ends up gone either way, which is the same state. PUT is idempotent because storing the same complete order twice leaves the same order.

Why POST and PATCH are not. POST /orders twice can create two orders. A PATCH that says "add one pen" adds two pens if sent twice. A PATCH that only sets fields, "address is 1 High Street", happens to be idempotent, but the method itself does not promise it.

Why it matters for retries. A request that times out may or may not have reached the server. For an idempotent method, sending it again is safe whatever happened the first time, and HTTP clients and proxies retry such requests by themselves. For POST and PATCH, a retry may repeat the action, which is why they are not retried automatically and why writes that must be retryable use an idempotency key.

So every safe method is idempotent, but not the reverse: safety is about whether a request changes anything, idempotency about whether repeating it changes anything more.