BugForge
All lessons
Core · 03/05 7 min

Concurrency, retries & idempotency

Race conditions, idempotency keys, backoff with jitter: the 'production' bugs.

Check-then-act races

const seat = await Seat.findById(id);
if (!seat.booked) { seat.booked = true; await seat.save(); } // two requests can both pass the check

Make the check and the write one atomic operation:

const r = await Seat.updateOne({ _id: id, booked: false }, { $set: { booked: true } });
if (r.modifiedCount === 0) return res.status(409).json({ error: "already booked" });

Idempotency keys

Clients retry. A payment endpoint must not charge twice. Store the result under the client's Idempotency-Key; a repeated key returns the stored response instead of re-executing.

Retries

  • Only retry transient failures (timeouts, 503, 429), never 400s.
  • Exponential backoff: base * 2^attempt, capped.
  • Jitter (random spread) stops every client retrying in lock-step.
  • Always cap attempts; surface the last error.

Rate limiting

Fixed window is simple but bursty at boundaries; sliding window or token bucket smooths it. Key by user or IP, return 429 with Retry-After.

Next in Core
DSA pattern cheat sheet