APIs and integrations

5 min read

Idempotency: Why a Repeated Request Must Not Create a Second Payment

A network connection can fail after an operation has already succeeded. The user presses the button again, the client retries — and the system must understand that this is still one operation, not two.

One of the most unpleasant classes of failures looks harmless: a client sends a request, gets no response, and sends it again. The problem is that the first request may already have succeeded.

For reading data, that is usually fine. For payments, order creation, bookings, or loyalty rewards, a retry can become real money and a real customer complaint.

What problem are we solving?

An idempotent operation produces the same business outcome even if the same request arrives several times.

Typically the client sends a unique operation identifier. The system remembers that the request has already been processed and returns the previous result instead of creating another order or charge.

This matters anywhere retries are unavoidable: mobile networks fail, services retry temporary errors, and queues may deliver the same message more than once.

What does the business gain?

The main benefit is lower risk of duplicate operations where a technical error directly becomes money, refunds, support work, and lost trust.

The company can safely use automatic retries after temporary failures. That improves completion rates without forcing a choice between two bad options: never retry and lose transactions, or retry and sometimes create duplicates.

It also reduces the cost of incident handling. A duplicate payment is not just a software defect; it involves support, refunds, accounting, and customer experience.

What does the team gain?

The team gets a more predictable retry model. Retrying a critical operation no longer has to be dangerous by default.

But the team must define the business operation boundary, how idempotency keys are stored, how long they live, and what happens after partial execution.

It is important not to confuse an identical HTTP request with one business intent. The key should represent the intent of the user or calling system.

What does the customer gain?

The customer gets a calmer product: pressing the button twice or recovering from a network error should not create a second order.

Well-designed idempotency is almost invisible. The user simply sees one completed operation, regardless of how many technical attempts happened underneath.

What do we pay for it?

The price is state that the system has to store and check. There are idempotency tables or caches, cleanup rules, and races between concurrent requests.

The system also needs a rule for what happens if the same key arrives with different parameters. Silently accepting that case can hide a client-side error.

When do you not need idempotency?

Not every action needs a dedicated mechanism. Read operations are usually naturally safe to repeat. For simple internal actions, the cost of extra state may exceed the risk of duplication.

But if repeating one operation can create a second financial or legally meaningful result, idempotency should be discussed before production.

What should we ask before deciding?

In the end

Idempotency is not a way to prevent retries. Retries will still happen.

Its business value is making sure a technical retry stays a technical event instead of becoming a second payment, order, or real-world obligation.