# Race Condition

URL: https://softwaredictionary.org/terms/race-condition
Category: Operating Systems
Last updated: 2026-09-30

In short: A race condition is a bug where a program's result depends on the unpredictable timing of threads, processes, or requests that use shared data at the same time.

## What is a race condition?

A race condition happens when two or more operations run concurrently, touch the same data or resource, and at least one of them changes it, so the result depends on which one happens to go first. Because the timing changes from run to run, the program may work correctly thousands of times and then fail once, which makes race conditions some of the hardest bugs to reproduce.

The classic case is `counter += 1`, which is really three steps: read the value, add one, and write it back. If two threads both read 5, both write 6, and one increment is lost. Another common pattern is check-then-act, such as checking that a file doesn't exist and then creating it, while another process creates it in between; this is called time-of-check to time-of-use (TOCTOU) and is also a well-known class of security vulnerability. Races are not limited to threads: two web requests buying the last concert ticket, or two processes writing the same file, can race too.

Imagine two people sharing a bank account who check the balance of $100 at two ATMs at the same moment. Both see enough money, both withdraw $80, and without coordination the bank lets both happen. Fixes include mutexes and other locks, atomic operations, database transactions with a suitable isolation level or optimistic locking, and designs that avoid shared mutable state, such as immutable data or message passing. Tools such as thread sanitizers and Go's race detector help find races during testing.

Race conditions are often mixed up with deadlocks. With a race condition the program keeps running but produces wrong results; with a deadlock it stops making progress. The two are linked, because adding locks to fix a race can create a deadlock if they are acquired in inconsistent orders. Mutexes and semaphores are the tools; the race condition is the bug they prevent.

## Key takeaways

- A race condition makes the outcome depend on the timing of concurrent operations.
- Read-modify-write and check-then-act sequences are the most common causes.
- Races can happen between threads, processes, or separate web requests.
- Locks, atomic operations, and transactions are the usual fixes.
- A race gives wrong results, while a deadlock stops progress entirely.

## Example: A race between two async requests in JavaScript

```javascript
// Two requests try to buy the last ticket at the same time
async function buyTicket(userId) {
  const event = await db.getEvent(1);  // both requests read seatsLeft = 1
  if (event.seatsLeft > 0) {           // both pass the check...
    await db.createOrder(userId);
    await db.updateEvent(1, { seatsLeft: event.seatsLeft - 1 });
  }
}
await Promise.all([buyTicket("ada"), buyTicket("linus")]); // 2 orders, 1 seat

// Fix: make the check and the update one atomic step in the database:
// UPDATE events SET seats_left = seats_left - 1
//   WHERE id = 1 AND seats_left > 0
// ...and create the order only if exactly one row was updated.
```

## Frequently asked questions

**What is the difference between a race condition and a deadlock?**

A race condition lets the program keep running but can corrupt data or produce wrong results. A deadlock freezes the threads involved because each waits for a resource another one holds.

**Can race conditions happen in single-threaded JavaScript?**

Yes. Code never runs in parallel on one thread, but every `await` lets other tasks run in between, so two async operations can still interleave around shared data or an external database.

**What is the difference between a data race and a race condition?**

A data race is a specific low-level case: two threads access the same memory at the same time without synchronization, and at least one writes. A race condition is the broader problem of timing-dependent results, and it can exist even when every individual access is properly synchronized.

---

Software Dictionary: https://softwaredictionary.org/ · https://softwaredictionary.org/llms.txt
