Safe and idempotent HTTP methods

API design: REST, HTTP, GraphQL and gRPC Junior Python 3.13+ PostgreSQL 17+ Reviewed By Best Latest Apps

Predict the output

Each call runs once and then is retried once after a timeout. Which line leaves the account in a different state than a single call would?

Python 3.13
acct = {"balance": 100}

def put_balance(v: int) -> None:
    acct["balance"] = v

def post_deposit(v: int) -> None:
    acct["balance"] += v

for f, v in ((put_balance, 150), (post_deposit, 10)):
    f(v)
    f(v)
print(acct["balance"])

Options
Hint 1 of 1

Which one depends on the current value?

Choose an answer, then open Show answer below to check it.

Show answer

Answer: A post_deposit: the balance ends at 170, not 160

Correct. Setting a value twice is the same as once; adding twice isn't.

Idempotent means repeating a call leaves the same state as making it once. Setting balance = 150 twice still leaves 150, but adding 10 twice adds 20, so a blind retry of a POST-style deposit double-counts.

Why not the others?
  • B put_balance: the balance ends at 300. PUT-style replacement sets 150 both times.
  • C Neither: the balance ends at 160. The deposit ran twice.
  • D Both change it twice. Replacing with the same value is idempotent.

30-second answer

Safe methods (GET, HEAD, OPTIONS) shouldn't change state. Idempotent methods give the same server state whether a request runs once or several times: GET, HEAD, PUT, DELETE and OPTIONS. POST isn't idempotent, and PATCH isn't guaranteed to be. That matters because clients, proxies and load balancers retry after timeouts; a retried idempotent request is harmless, while a retried POST can create a second order unless you add an idempotency key.

Practise saying it · 30 s. No recording, just a timer

Explain safe vs idempotent.

Say your answer out loud, then check which of these points you covered:

  • Safe: no state change
  • Idempotent: same state after repeats
  • PUT and DELETE idempotent
  • POST is not
  • Retries depend on it

Deep dive

Idempotent is about server state, not the response: a second DELETE may return 404, which is fine.

PUT is idempotent because it replaces the whole resource with the same representation.

PATCH can be made idempotent (set a field) or not (append to a list, increment).

Some proxies and HTTP clients retry idempotent methods automatically on connection failure.

Common mistakes

  • Changing state on GET (tracking pixels that delete things).
  • Saying POST is idempotent.
  • Using PUT with increments ('add 5 to balance').

Senior take & follow-ups

Define both terms, list the methods, and connect it to retries.

Follow-up questions

Think of your answer first, then open the hint.

  1. Is DELETE idempotent if the second call returns 404?

    Show hint

    Yes: the state after both is 'gone'.

  2. How do you make POST safe to retry?

    Show hint

    Idempotency-Key header stored with the result.

Suggest a fix if something here is wrong or out of date.