skip to content

questions

5

In HTTP, what does it mean for a request method to be "safe" versus "idempotent", and which of the standard methods have each property?

level: juniorimportance: must knowfreq 78%

answer

  1. Safe = read-only intent, no accountability
  2. Idempotent = same end state after N identical requests
  3. GET/HEAD/OPTIONS/TRACE safe; +PUT/DELETE idempotent
  4. POST neither; PATCH depends on the patch doc
  5. Safety ⊂ idempotency; neither implies cacheable

basics

~20 s

Safe means the method is read-only: the client asks for nothing to change. Idempotent means sending the identical request many times leaves the server in the same state as sending it once. GET, HEAD, OPTIONS, TRACE are safe (and therefore idempotent); PUT and DELETE are idempotent but not safe; POST and PATCH are neither by definition.

solid answer

~50 s

They answer two different questions. **Safe** (RFC 9110 §9.2.1) means the request is essentially read-only — the client does not request any state change, so a crawler, prefetcher or proxy may issue it freely. GET, HEAD, OPTIONS and TRACE are safe. **Idempotent** (§9.2.2) means the *intended effect on the server* of N identical requests is the same as one. GET, HEAD, OPTIONS, TRACE, PUT and DELETE are idempotent. PUT is a full replacement — writing the same representation twice ends in the same state. DELETE twice leaves the resource gone either way. **POST is neither**, because it means "process this" — two POSTs to `/orders` normally create two orders. PATCH is not idempotent in general; it depends on the patch document. Safety implies idempotency, not the reverse. And idempotency is a promise about *state*, not about getting an identical response — the second DELETE may legitimately return 404.

code

http · 15 lines
http
PUT /users/42 HTTP/1.1
Host: api.example.com
Content-Type: application/json

{"name":"Ada","role":"admin"}

HTTP/1.1 200 OK

PUT /users/42 HTTP/1.1
Host: api.example.com
Content-Type: application/json

{"name":"Ada","role":"admin"}

HTTP/1.1 200 OK

go deeper

for a junior

Give the two one-line definitions and the method table correctly, and name POST as the odd one out. That alone passes the screen.

for a middle

Add why the properties exist — crawlers/prefetchers rely on safety, automatic retry relies on idempotency — and explain that PATCH's status depends on the patch document.

for a senior

Frame them as contracts consumed by software that never read your docs, and be precise that idempotency is about server state, not about identical responses; mention that violating the contract is a real production hazard, not a style issue.

for a principal

Talk about them as the API's interoperability boundary: which guarantees you can safely expose to unknown intermediaries, how method choice constrains your retry and caching architecture, and where you must layer an application-level contract because the method gives you nothing.

## Two separate properties RFC 9110 (the current HTTP semantics spec) defines two independent properties of request methods. Interviewers ask about them together because candidates routinely collapse them into one idea. **Safe** — §9.2.1. A method is safe if the request is, in the spec's words, "essentially read-only": the client does not *request* any state change on the origin server. Safety is a property of what the client asks for, not a guarantee that literally nothing on the server moves. A GET may still append a log line, bump a hit counter, or warm a cache — those are the server's own doing, and the important consequence is that **the user cannot be held accountable** for them. Safe methods in the standard: **GET, HEAD, OPTIONS, TRACE**. **Idempotent** — §9.2.2. A method is idempotent if the intended effect on the server of several *identical* requests is the same as the effect of a single one. Idempotent methods in the standard: **GET, HEAD, OPTIONS, TRACE, PUT, DELETE**. Safety implies idempotency (doing nothing N times is the same as doing nothing once). The converse is false: PUT and DELETE are idempotent but definitely not safe. ## Method by method | Method | Safe | Idempotent | |---|---|---| | GET, HEAD, OPTIONS, TRACE | yes | yes | | PUT | no | yes | | DELETE | no | yes | | POST | no | no | | PATCH | no | no (not by definition) | **PUT** carries a complete replacement representation: "make the resource at this URI look like this." Applying the same replacement twice ends in the same state, so it is idempotent. **DELETE** asks for the resource to be removed. After the first success it is gone; the second request cannot remove it "more". The state converges, which is what idempotency requires. **POST** means "process this representation according to the resource's own semantics." The archetypal use — appending to a collection — creates a new subordinate resource each time, so two identical POSTs to `/orders` produce two orders. That is why POST is the method you cannot blindly retry. **PATCH** (RFC 5789) applies a partial modification. Whether it is idempotent depends entirely on the patch document: replacing a field with a fixed value is idempotent; `{"op":"add","path":"/tags/-"}` or "increment balance by 10" is not. The spec therefore refuses to declare PATCH idempotent, though a given endpoint may be. ## Why the properties exist They exist so that **intermediaries and clients can act automatically without asking anyone**. - Safety is what lets a search-engine crawler, a browser link-prefetcher, or a link preview bot follow every GET it finds. It is the reason the classic `GET /admin/deleteUser?id=42` design is a genuine defect and not just poor taste: something will eventually crawl it. - Idempotency is what licenses **automatic retry**. RFC 9110 says a client MAY automatically retry a request when the method is idempotent and it received no response. Connection pools, HTTP/2 stacks and reverse proxies rely on exactly this rule. So the properties are not academic taxonomy — they are the contract that makes retrying and prefetching safe for software that has never seen your API. ## The confusions to avoid **Idempotent does not mean "returns the same response."** It constrains server state, not the status line. `DELETE /orders/7` may return 204 the first time and 404 afterwards and still be perfectly idempotent. Likewise a GET is idempotent even though the body changes between calls because someone else wrote data. **Idempotent does not mean cacheable.** Cacheability is a third, separate property; PUT and DELETE are idempotent and not cacheable at all. **These are contracts, not enforcement.** Nothing stops you implementing a GET handler that charges a credit card. The spec's position is that you have then violated the method contract, and the resulting damage — a crawler charging every card — is yours. Conversely, a server *can* make POST behave idempotently for a given endpoint, but a generic client still must not assume it, because the assumption is made per-method, not per-endpoint. **"POST is never idempotent" is too strong.** POST has no *defined* idempotency, which is why generic intermediaries won't retry it. An individual POST endpoint may be built to deduplicate — that is an application-level contract layered on top, and it must be advertised explicitly rather than inferred.

  • Is every idempotent method also safe?
    No — the implication runs only one way. PUT and DELETE are idempotent but they change server state, so they are not safe. Every safe method is idempotent, because a request that is intended to change nothing changes nothing no matter how often you send it.
  • If a POST endpoint deduplicates internally, is POST now idempotent?
    That endpoint behaves idempotently, but the method POST still is not. Idempotency in HTTP is a per-method contract that generic clients, proxies and libraries rely on without inspecting your API, so they will still refuse to auto-retry a POST. Endpoint-level deduplication has to be advertised as an explicit application contract.
  • Does idempotency mean the two responses must be identical?
    No. Idempotency constrains the effect on server state, not the response. A second DELETE may return 404 instead of 204, and a GET may return a different body because another client wrote data in between; both remain idempotent.

Safe is reading a light switch's position; idempotent is flipping it to 'off' — do it five times, the room is equally dark. POST is 'add one more lamp to the room'.

saying these in an interview costs you the question

  • Saying safe and idempotent mean the same thing.
  • Claiming an idempotent request must return an identical status and body every time.
  • Asserting GET is guaranteed to have zero server-side effects (logging and counters are allowed; safety is about intent and accountability).
  • Listing POST as idempotent because 'my endpoint checks for duplicates'.
  • Treating idempotent as a synonym for cacheable.

context

open as a page

A client calls DELETE on a resource and gets HTTP 204; the identical DELETE is sent again and returns HTTP 404. Has the server broken DELETE's idempotency guarantee? Explain what that guarantee actually covers.

level: middleimportance: must knowfreq 62%

basics

~20 s

No. Idempotency constrains the server's end state, not the response. After one DELETE or five, the resource is gone — that is the guarantee. Returning 204 then 404 is legitimate. Returning 204 both times is equally legitimate; pick one and document it.

open as a page

An HTTP client sends a request, the TCP connection drops, and no response ever arrives. Under HTTP's own rules, when may the client automatically retry that request, and what must it never retry automatically?

level: seniorimportance: must knowfreq 55%

basics

~20 s

A client may automatically retry only if the method is idempotent (GET, HEAD, OPTIONS, TRACE, PUT, DELETE) and it received no response — or if the server explicitly signalled the request was not processed. Never auto-retry POST or PATCH: a lost response is indistinguishable from a lost request, so the retry may duplicate the effect.

open as a page

Is the HTTP PATCH method idempotent? Explain what determines the answer and how you would make a PATCH endpoint safe to repeat.

level: middleimportance: should knowfreq 45%

basics

~20 s

Not by definition. RFC 5789 leaves PATCH non-idempotent because the patch document decides: setting a field to a fixed value repeats harmlessly, but appending to an array or incrementing a number does not. An individual endpoint can be idempotent — but generic clients must not assume it.

open as a page

HTTP defines GET as a "safe" method. What exactly does safety promise, what breaks in production when a GET endpoint changes state, and are server-side effects like logging a violation?

level: middleimportance: should knowfreq 50%

basics

~20 s

Safe means the client does not request any state change, so the user cannot be held accountable for side effects. Server-side bookkeeping — logs, hit counters, cache warming — is allowed because the user didn't ask for it. Mutating GETs get triggered by crawlers, prefetchers and link-preview bots.

open as a page