Mikael Lirbank — February 2026
Harnessing Postgres race conditions
Without race condition tests, every possible race condition in your system is one refactor away from hitting production.
Synchronization barriers let you write those tests with confidence.
What a race condition looks like
You have a function that credits an account. It reads the current balance, adds an amount, and writes the new value back.
When two requests run this concurrently — two $50 credits to an account with a $100 balance — the timing can line up like this:
P1: SELECT balance → 100 P2: SELECT balance → 100 ── both read 100, now both write based on it ── P1: UPDATE balance = 150 P2: UPDATE balance = 150
Both read 100. Both compute 150. Both write 150. Final balance: $150 instead of $200. One $50 credit vanished. No error was raised. No transaction was rolled back. The database did exactly what it was told.
This is the shape of every write race condition: two operations read the same stale value, then both write based on it. The second write overwrites the first. In a system that handles money, that's a customer with a wrong balance and no error in any log to explain it.
... continue reading