concurrency

Idempotent Job with Advisory Lock

I reached for idempotency the moment retries started duplicating side effects. In Advisory lock helper, I generate a deterministic lock ID and use pg_try_advisory_lock to ensure only one worker owns the critical section; the ensure block always calls

Transactional “Reserve Inventory” with SELECT … FOR UPDATE

Inventory systems are concurrency systems. Lock the row, verify available quantity, then write the reservation in the same transaction. It’s the simplest correct starting point.

Optimistic Locking for Collaborative Edits

If multiple admins edit the same record, use lock_version. Rails will raise on conflicting updates, and you can show a friendly “this changed underneath you” message. It prevents subtle lost updates.

Safer “find or create” with Unique Constraint + Retry

Race conditions happen. The correct “find or create” in production uses a unique constraint and a retry on conflict, not a naive check-then-insert. Let the database serialize the race.

SQL upsert for counters (ON CONFLICT DO UPDATE)

Counters are classic race-condition bait. If two requests read, increment, and write, you’ll lose updates under load. I prefer letting Postgres do the atomic work with an upsert: INSERT ... ON CONFLICT ... DO UPDATE to increment the existing value. Th

Parallelize Independent External Calls (in a bounded way)

If you have to hit multiple APIs, you can cut tail latency by running calls concurrently. Keep it bounded and use timeouts. Rails itself is thread-safe for reads; be careful with DB connections and use with_connection for threaded work.

Postgres advisory lock for one-at-a-time work

Sometimes you just need ‘only one worker does this thing at a time’, and building distributed locks from scratch is risky. Postgres advisory locks are a pragmatic option when your DB is already the source of truth. I derive a deterministic lock key (l

Prisma transaction with retries for serialization errors

Under real concurrency, even ‘simple’ write paths can hit serialization failures, especially with stricter isolation levels. Instead of pretending it won’t happen, I wrap the transaction in a small retry loop with jitter. I only retry on known transie

Atomic “Read + Mark Processed” with UPDATE … RETURNING

If you have a queue table, avoid races by selecting and updating in one statement. Postgres UPDATE … RETURNING is the simplest building block for a correct custom queue / maintenance pipeline.

Django select_for_update for database locking

select_for_update() locks rows until transaction completes, preventing race conditions. I use it for operations requiring read-modify-write atomicity like decrementing stock or updating counters. The lock is released on transaction commit/rollback. Fo

Redis-Based Distributed Mutex (with TTL)

Sometimes you need “only one runner globally” (backfills, refresh jobs). A Redis mutex with TTL avoids deadlocks if the process dies. It’s not perfect, but it’s a solid pragmatic tool.