Duplicate Orders During High Traffic
What happened?
A Node.js API creates an order when a customer clicks the checkout button.
Under normal traffic, everything works correctly. However, when the same request reaches the server twice within a few milliseconds, two orders are sometimes created for the same payment.
The frontend sends only one request, and the payment provider reports a single successful transaction.
The issue is difficult to reproduce locally but appears occasionally in production during network retries and high traffic.
Environment
Error Message
No error was reported.
Both requests returned:
201 Created
What was actually wrong?
The API relied on a Redis lock to prevent duplicate order creation, but the lock was released before the PostgreSQL transaction had completely finished.
Two requests could therefore pass through during a small timing window.
The application also did not have a database-level unique constraint on the payment transaction ID, so PostgreSQL accepted both records.
The real problem was relying on application-level locking without enforcing the uniqueness requirement at the database level.
The Fix
Add a unique constraint to the payment transaction ID:
ALTER TABLE orders ADD CONSTRAINT unique_payment_transaction UNIQUE (payment_transaction_id);
Then handle duplicate-key errors safely in the Node.js API.
The Redis lock can still be used to reduce unnecessary concurrent processing, but the database constraint becomes the final guarantee against duplicate orders.
The order creation logic should also keep the required operations inside a single PostgreSQL transaction.
What I Learned
Distributed locks can reduce race conditions, but they should not be the only protection for data that must be unique.
If a business rule says “this payment can only create one order,” enforce that rule at the database level as well.
Application-level protection can fail because of timing, retries, crashes, or multiple application instances.