Buying Technology

    How do you stop double bookings when a request is retried?

    Retried taps, flaky networks and two people clicking at once are normal. Idempotency keys, version-guarded writes and transactions are how a booking system survives them. With what we found in our own queue.

    GC
    GarunaCDX Editorial
    Editorial team
    Oct 19, 2026 4 min read
    Key takeaways
    • An idempotency key makes a retried request safe: same key, same result, no second booking.
    • A version-guarded write rejects the second of two conflicting changes instead of silently overwriting.
    • A change across several rows should be one transaction, or a failure partway leaves the data half-updated.
    • Test with concurrent runs, not just one user clicking once.
    • Our own audit found a half-updated queue. The fix is tested and not yet in production.

    Quick answer

    Use an idempotency key so a retried request is recognised as the same request, and a version-guarded write so two people changing one record can't both succeed. Make any change that touches several rows one transaction. Then test with concurrent runs. A retried tap, a flaky connection and two receptionists clicking together are normal, so build for them.

    The short answer

    Three things cause most duplicate or corrupted bookings: the same request arriving twice, two changes to one record arriving together, and a multi-step change that fails halfway. Each has a standard guard.

    Why engineers ask this

    Because the happy path always works in a demo. Real systems get a patient who taps twice on a slow connection, a phone that retries after a timeout, and two staff who press a button within the same second. If your booking logic assumes one clean request at a time, it will break exactly when the clinic or shop is busiest.

    What good looks like: three guards

    FailureWhat happens without a guardThe guard
    The same request arrives twiceTwo bookings for one tapIdempotency key. The client sends a unique key. A repeated key returns the first result and does nothing new.
    Two changes hit one record togetherThe later one silently overwrites the earlierVersion-guarded write. The write carries the version you read. If the record has moved on, it’s rejected and the client reloads.
    A change spans several rows and fails partwayThe data is half-updated, such as a queue with a gap or a duplicateOne transaction, under a lock on the one hot record. Either everything changes or nothing does.

    On top of the guards, test them with concurrent runs. A test that fires a request once proves nothing about retries. A test that fires many at the same moment proves a lot.

    Optimistic versioning fits most booking screens, since conflicts are rare and a rejected write is cheap to retry. A short lock fits the one record where conflicts are common, such as advancing a single doctor’s queue.

    What we found in our own queue

    Proof · grade 4 · our own build for an independent client

    A clinic-queue platform, built and tested on a demo clinic ahead of launch. One of the fixes below is tested but not yet in production. Nothing here has been proven under real clinic load.

    On the clinic-queue platform we built, booking and queue advance both require an idempotency key plus a version-guarded write, so a retried tap can’t book twice.

    Queue advance is where we found a real problem. A review showed that advancing a queue was a series of separate writes, so a failure partway could leave the queue torn. We moved it into one transaction under a per-doctor lock. It passed 48 assertions and two concurrency runs locally. It isn’t deployed to production yet, and we won’t call it fixed until it is.

    The case that makes this concrete is an emergency walk-in. Reception inserts the patient right after the consultation in progress and everyone behind renumbers. If a doctor taps End at the same moment, two changes touch the same queue at once. That is exactly the situation the transaction and the lock exist for.

    We found the half-updated queue in an audit, not in our tests. That’s the main lesson: test write paths under concurrent load earlier.

    Where this doesn’t apply

    Where this doesn't apply

    A single-user tool, or a screen where one person owns each record, doesn’t need this machinery. And some businesses overbook on purpose, such as airlines or restaurants with expected no-shows. In that case the double booking is a policy, so make it a visible rule, not an accident of retries. We haven’t measured how often these failures occur in practice, so we don’t quote a rate.

    Questions to ask any vendor, including us

    1. How does a retried request avoid creating a second record?
    2. What happens when two people change the same record at the same time?
    3. Which multi-step changes run as a single transaction?
    4. Show me the concurrency tests, not only the single-user ones.
    5. What did your last audit find in the write paths, and is it fixed in production?
    Booking logic review
    Describe your booking flow. We'll point to where retries and concurrent clicks can break it.
    Book a review

    Next: how to test before real users arrive and one backend for the app and the web. Part of the guide Buying custom software and hiring a tech vendor.

    The facts about our queue come from our clinic-platform brief and notes and are tracked in our claim ledger. The three guards are standard engineering practice and our explanation of them, not a claim about a third party. We hold no incident-rate data, and no figure on this page comes from a third party.

    Your verdict
    Was this article useful?
    GC
    Written by
    GarunaCDX Editorial
    Editorial team

    Engineers, product and growth folks at GarunaCDX writing about the systems we build for clients.

    View all articles
    Share
    Planning something similar?

    Let's talk about your build.

    Tell us what you are building. A founding engineer replies within one working day with how we would approach it.

    FAQ

    Frequently asked questions

    A unique value the client sends with a request. If the same key arrives twice, the server returns the first result instead of doing the work again. It makes a retried booking safe.

    A write that includes the version of the record you last saw. If someone else has changed it since, the write is rejected and you reload. It prevents the later change from silently overwriting the earlier one.

    Optimistic suits most booking screens: conflicts are rare, so you check at write time and retry. A lock held for a short time suits one hot record where conflicts are common, for example advancing a single doctor's queue.

    Sometimes, on purpose. Some businesses overbook by design and manage the overflow. That should be a rule the business chose, not an accident of retries.

    The GarunaCDX build log

    Industry insights, once a month

    New case studies, healthcare, marketplace, B2B SaaS and industrial breakdowns, and the engineering notes behind what we ship. One short email a month, no fluff.

    We never share your data — see our Privacy Policy for details.