Idempotency in API Design: Why It Matters More Than You Think
Idempotency in API design means that calling the same API operation multiple times with the same inputs produces the same result as calling it once. An idempotent API handles network retries, duplicate submissions, and client-side errors gracefully. An API that lacks idempotency turns network instability into data corruption.
Written by Yashveer Singh, founder of Yashveer Labs.
What you need to know
- Network requests fail and get retried. If your API is not idempotent, every retry is a potential duplicate execution. In a payment context, that means a double charge.
- Idempotency is an architectural decision that is much cheaper to build from the start than to add after the first customer complaint.
- The most critical endpoints for idempotency are any that charge money, create resources, or send communications. These are the operations where duplicate execution has visible consequences.
- HTTP GET, PUT, and DELETE are idempotent by the HTTP specification. HTTP POST is not, which is why payment and creation endpoints need explicit idempotency key support.
- Idempotency keys do not need to be complex. A UUID generated by the client, stored with the result for twenty-four to seventy-two hours, is sufficient for most SaaS use cases.
The core argument
The problem idempotency solves is best understood through the failure mode it prevents. A user submits a payment form. The request reaches the server, the charge is processed, but the server response is lost in transit due to a network error. The client, receiving a timeout or a connection error, retries the request. Without idempotency, the server processes the payment a second time and the user is charged twice. The server never saw a duplicate. The client followed the correct retry logic. The user is angry, the support ticket is open, and the refund is being processed. This is a completely preventable outcome.
The idempotency key pattern prevents it by making the payment operation aware of its own execution history. The client generates a unique key before the first attempt and sends it with every retry. The server processes the first request, stores the result against the key, and returns the result. For every subsequent request with the same key, the server returns the stored result without executing the operation again. The client gets a consistent response. The user is charged once. The support ticket is never opened.
Building this pattern into the API from the first version requires adding one column to the relevant database tables, one middleware layer that checks the key before processing, and documentation that tells clients to generate and send keys for write operations. The cost is a day of engineering work. The cost of not building it is the first double-charge incident, which generates customer support overhead, refund processing cost, and platform risk if it triggers a payment processor review. I build idempotency into every payment and creation endpoint from the first version on every project.
Common mistakes
- Relying on the client to prevent retries. Clients retry on network errors. This is correct behavior. The server's idempotency layer is the right place to handle the consequences, not the client's retry logic.
- Not including idempotency in email sending. A double-processed payment is obvious. A double-sent welcome email is annoying but less obvious. Both are preventable with the same pattern.
- Setting idempotency key TTL too short. A key that expires after one hour does not protect against retries that happen after a delayed client recovery. Twenty-four hours is the minimum for most use cases.
- Not documenting idempotency key requirements for API consumers. If the client does not know they should send keys, they will not. Document it explicitly in the API reference.
- Implementing idempotency on read endpoints. Reads are idempotent by nature and do not need key management. Focus the implementation on write operations with side effects.
Where to start
- Identify every write endpoint in your API that has side effects. Payment processing, account creation, order placement, notification sending. These are your idempotency candidates.
- Add an idempotency key column to the relevant tables and a check in the handler. The check is: if a record with this key exists and was processed successfully, return the stored result. Otherwise, process and store.
- Update your API documentation to require idempotency keys for write operations. Specify the expected format, the header name, and the behavior on key reuse.
Related reading
Frequently asked
Why you should hire Yashveer Singh for this
The kind of work this article describes is the kind of work I do every week. Production deployments, scaling decisions, the architecture choices that compound over years. I am Yashveer Singh, founder of Yashveer Labs. If you need this done, I do not need to be sold on the brief. Send me what you have and I will tell you what it actually takes.
Posts that line up with this one.
- SaaS Architecture and Scaling
Internal Admin Tools: Build vs Buy vs Retool
Every SaaS needs internal tools. The question is whether to build them, buy a platform like Retool, or use a lighter alternative. Here is the decision framework that saves engineering hours without creating tool debt.
- SaaS Architecture and Scaling
Job Failure Recovery: How Good SaaS Companies Sleep at Night
Every background job will fail eventually. The companies that sleep at night are the ones that built failure recovery into the system from day one, not as an afterthought when something broke in production.
- SaaS Architecture and Scaling
Monolith vs Microservices: Why Most Startups Get It Wrong
Microservices are the architecture that works at Netflix and fails at early-stage startups. Here is why the monolith is the right default, when microservices become rational, and how to make the transition without breaking everything.
- SaaS Architecture and Scaling
Multi Region Deployment: When It Is Worth the Pain
Multi-region deployment multiplies your infrastructure complexity. Here is when the latency reduction or compliance requirement justifies that complexity, and what the implementation actually looks like for a SaaS product.