Portfolio
Back to Engineering Notes
MistakesJanuary 20, 2024

Credit Deduction Race Condition

How I introduced and fixed a race condition in the credit deduction system that allowed negative balances.

I initially implemented credit deduction without proper locking, which led to race conditions.

The Problem: - User makes multiple concurrent AI requests - Each request checks balance and deducts credits - Without locking, both could read same balance and both deduct - Result: Negative credit balance

The Fix: - Used PostgreSQL row-level locking (SELECT FOR UPDATE) - Wrapped credit check and deduction in a transaction - Added database constraint to prevent negative balances - Implemented optimistic locking for high concurrency

Lesson Learned: Financial operations require ACID transactions and proper locking. Don't assume "it probably won't happen" - concurrent requests are common in production.

What I'd change: I should have implemented locking from the start. The fix was straightforward, but it required a migration and careful testing to ensure no edge cases.