Questions › Networking/Security
What do 'safe' and 'idempotent' mean for HTTP methods, and why do these properties matter in practice?
Understanding method semantics that browsers, caches, and retry logic depend on — not just 'GET reads, POST writes'.
Two properties define how a method is allowed to behave. SAFE means the request has no side effects on the server — it only reads. GET, HEAD, and OPTIONS are safe. IDEMPOTENT means making the request N times has the SAME effect on server state as making it once. GET, HEAD, PUT, and DELETE are idempotent; POST and PATCH are generally NOT. Note safe implies idempotent (reading twice changes nothing), but idempotent does not imply safe (DELETE changes state, but deleting twice leaves the same 'gone' state as deleting once). Why these matter beyond trivia: (1) CACHING — safe methods (GET) can be cached by browsers, CDNs, and proxies because they don't change anything; POST responses generally aren't cached. Putting a state-changing action behind GET is a real bug: a prefetcher, a crawler, a browser preloader, or a cache can fire it unexpectedly (the classic 'a search-engine bot deleted our records by following GET /delete?id=5 links'). (2) RETRIES — clients, proxies, and load balancers safely RETRY idempotent requests after a network hiccup because a duplicate is harmless; they must NOT blindly retry a non-idempotent POST, or you get double charges / double orders. This is exactly why 'submit payment' is a POST and why real systems add an IDEMPOTENCY KEY so even a POST can be safely retried without duplicating the effect. (3) Browser behavior — refreshing or navigating back to a POST prompts 'resubmit form?' precisely because POST isn't idempotent. So the practical rules: use GET only for reads (never for actions), use POST for non-idempotent creates/actions, use PUT/DELETE when the operation genuinely is idempotent, and design write endpoints so retries don't double-apply. Choosing the method by its semantics — not just 'GET vs POST' by habit — is what lets the whole caching/retry infrastructure around your app behave correctly.
Choosing a method for an endpoint; deciding what a client may retry; avoiding action-behind-GET bugs.
Method Safe? Idempotent? Notes
------- ----- ----------- ---------------------------------
GET yes yes cacheable; reads only
HEAD yes yes GET without a body
PUT no yes full replace; retry-safe
DELETE no yes deleting twice == deleted once
PATCH no no* partial update
POST no no create/action; NOT retry-safe
Consequences:
* caches/prefetchers may fire GET -> never hide an action behind GET
* proxies/clients retry idempotent methods -> POST needs an idempotency key
* browser "resubmit form?" prompt exists because POST isn't idempotent