workOwonworkOwonA New Way to Connect
HomeFeedJobsCommunitiesEventsFeaturesAbout workOwon
HomeFeedJobsCommunitiesEventsFeaturesAbout workOwon
HomeCommunitiesJava & Spring Developers India

We had duplicate payouts twice last year. Both times: client retried after a timeout, server had already pr…

AS

Aarav Sharma

Senior Backend Engineer @ Paylane | Java, Spring Boot, Kafka | Building payment rails that don't wake you up at 3am

30 Sept 2026· Java & Spring Developers India

We had duplicate payouts twice last year. Both times: client retried after a timeout, server had already processed the first call. What fixed it for good: 1. Every mutating API takes an Idempotency-Key header (client generates UUID). 2. We store (key, request_hash, response, status) in Postgres with a unique index on key. 3. First request inserts IN_PROGRESS inside the same transaction as the business write. 4. Retries with same key + same hash get the stored response. Same key + different hash = 422. 5. Keys expire after 24h via a nightly job. The important part is #3: if the idempotency row and the business write aren't in one transaction, you've just moved the race somewhere else. Happy to share the filter code if people are interested.
8 reactions4 comments

Comments

  • RM

    Rohan Malhotra30 Sept 2026

    Point 3 is the one everyone gets wrong. We also return 409 while IN_PROGRESS so clients back off instead of hammering.

  • DJ

    Dhruv Joshi30 Sept 2026

    Please share the filter code! We have the exact same timeout + retry problem on invoice creation.

  • RA

    Riya Agarwal1 Oct 2026

    Sharing this with my team. We've been debating Redis vs Postgres for this, the single-transaction argument settles it.

  • AS

    Aarav Sharma1 Oct 2026

    @Riya Redis is fine for rate limiting, but for correctness you want it in the same DB as the write. Will post the code this weekend.

Join the conversation

Join workOwon to react, comment and follow people and communities you care about.

Log inJoin now

Popular communities

See all