A specialized backend system designed to prevent overselling during high-traffic "Flash Sales"
During a flash sale (e.g., PS5 launch, concert tickets), thousands of users attempt to purchase the same limited-stock item at the exact same millisecond. If the backend is not properly synchronized, "Race Conditions" occur, allowing 500 users to successfully buy an item that only has 10 units in stock.
This project implements a highly scalable, data-integrous architecture to guarantee zero overselling, even under severe load tests of 500+ concurrent requests per second.
- In-Memory Caching (Redis): Handles the initial barrage of traffic with an atomic
DECRoperation, acting as a "Fast-Fail" mechanism to instantly reject users when stock theoretically hits zero. - Message Queuing (RabbitMQ): Accepted purchase intents are pushed to an asynchronous queue, decoupling the incoming web traffic from the heavy database lifting.
- Pessimistic Data Locking (PostgreSQL): Worker nodes consume the queue and use
SELECT ... FOR UPDATEto lock database rows at the hardware level, ensuring that the final source of truth decrements atomically and safely.
- Runtime: Node.js, Express.js
- Persistence: PostgreSQL (Primary DB), Redis (In-Memory Cache)
- Message Broker: RabbitMQ
- Performance Testing: k6 (Standalone Load Testing Worker)
- Docker & Docker Compose (Recommended) OR
- Local installations of PostgreSQL, Redis, and RabbitMQ
- Node.js v16+
-
Clone the repository:
git clone https://github.com/pranav14-1/inv_eng.git cd inv_eng -
Install dependencies:
npm install
-
Configure Environment: Create a
.envfile in the root directory:DB_USER=postgres DB_HOST=localhost DB_NAME=inventory_db DB_PASSWORD=your_password DB_PORT=5432 REDIS_URL=redis://localhost:6379 RABBITMQ_URL=amqp://localhost
-
Initialize Database:
node setup.js
-
Run the Application: Terminal 1 (Web Server):
node index.js
Terminal 2 (Queue Worker):
node worker.js
To prove the system's integrity, this project includes a k6 Load Test script that forces severe race conditions to validate our architectural decisions.
To run the test:
npm run test:load- Test Conditions: 500 Virtual Users, 10-second duration, max system throughput.
- Results: The Redis cache correctly fast-failed ~95% of requests instantly. The PostgreSQL lock securely processed the remaining valid orders. Stock mathematically bounded at exactly 0 with 0 negative inventories.
- Phase 0: Foundation & Environment Setup
- Phase 1: Data Integrity (Pessimistic Locking)
- Phase 2: Performance (Redis Integration)
- Phase 3: Scalability (Message Queues)
- Phase 4: Validation (Load Testing)
- Phase 5: UI/Frontend (Visualizing the Flash Sale)