Safe vs Idempotent HTTP Methods Explained
What safe and idempotent really mean in RFC 9110, why they are not the same property, and how each one shapes caching and retry behaviour.
Safe means read-only
A method is safe when a client requests it purely to read, with no intent to change anything on the server. RFC 9110 lists GET, HEAD, OPTIONS and TRACE as safe. Safe does not mean the server literally does nothing, since it may still write access logs or update counters, but those effects are its own responsibility and are invisible to the client. The practical payoff is that safe requests can be prefetched, crawled by search engines and repeated freely without a user worrying about side effects.
Idempotent means repeatable
A method is idempotent when sending it several times has the same effect on server state as sending it once. GET, HEAD, PUT, DELETE, OPTIONS and TRACE all qualify. DELETE is the classic example, because deleting a resource twice leaves it just as gone as deleting it once, even though the second call may return a 404. Idempotency is about the final state, not about identical response codes.
Why the two properties differ
Every safe method is idempotent, but many idempotent methods are not safe. PUT and DELETE change data yet stay idempotent because the outcome is fixed no matter how many times you repeat them. POST and PATCH sit outside both groups, since a POST can create a new record on every call and a PATCH that applies a relative change can compound. Keeping the two ideas separate stops you from assuming a method is harmless just because it is repeatable.
How it shapes retries and caching
These properties drive real client behaviour. Because idempotent requests can be retried safely, HTTP libraries and proxies will automatically resend a GET or PUT after a dropped connection, but they leave POST alone to avoid duplicate orders or payments. Caching keys off safety and the cacheable flag, which is why GET and HEAD responses are stored by browsers and CDNs while a POST response is passed straight through unless it carries explicit freshness headers.