A backend system for medicine delivery, built to solve a real problem that simple e-commerce clones usually skip: preventing overselling when multiple orders hit the same limited stock at the same time, automatically routing orders to another pharmacy when the closest one runs out, and propagating stock changes in real time across services.
This is not a UI-focused clone. The focus is on backend correctness under concurrent load — the kind of problem real quick-commerce and delivery platforms (Blinkit, Zepto, Apollo 24/7, etc.) have to solve at scale — and it's been load-tested to prove it.
Imagine 2 customers order the last strip of Paracetamol at the exact same second. Without careful handling, both orders can succeed even though only 1 unit exists — because both requests "check stock" before either one finishes "reducing stock." This project solves that using an atomic database update, so the check-and-reduce happens as a single, uninterruptible operation.
Tested with Apache Bench — 100 concurrent order requests fired at a stock row with exactly 50 units available:
| Metric | Result |
|---|---|
| Total requests | 100 (20 concurrent at a time) |
| Successful orders | 50 (exactly matching available stock) |
| Overselling incidents | 0 |
| Requests per second | ~300 |
| Mean response time | 59 ms |
| 95th percentile response time | 122 ms |
Final stock after the test: 0 (not negative, not still positive) — confirming the atomic update held up correctly under real concurrent load, not just in theory.
- Concurrency-safe stock updates — a single atomic SQL operation (
UPDATE ... WHERE quantity > 0) guarantees stock can never go negative, even under simultaneous requests. Load-tested and verified (see above). - Multi-pharmacy order routing — if the nearest/first pharmacy is out of stock, the system automatically tries the next pharmacy carrying the same medicine, instead of failing the order outright.
- Real-time stock sync via Kafka — every successful order publishes a stock-change event to a Kafka topic, so other services (search, notifications, etc.) can react instantly instead of polling the database.
- Delivery time estimation — a simple distance + prep-time formula estimates delivery time per pharmacy, returned with every successful order.
- REST API built with Spring Boot, backed by an H2 in-memory database for fast local development.
- Java 17 + Spring Boot 3.3
- Spring Data JPA (Hibernate)
- Apache Kafka (via Docker)
- H2 Database (in-memory, for local dev)
- Maven
- Apache Bench (load testing)
| Method | Endpoint | Description |
|---|---|---|
| GET | /stock |
View all stock across all pharmacies |
| GET | /stock/search?medicineName=X |
View stock for one medicine across all pharmacies |
| POST | /stock |
Add new stock (body: medicineName, pharmacyName, quantity) |
| POST | /stock/{id}/order |
Order from one specific pharmacy's stock row |
| POST | /stock/order?medicineName=X |
Smart order — automatically tries every pharmacy carrying this medicine until one fulfills it, publishes a Kafka event, and returns an ETA |
Start Kafka:
docker compose up -dStart the app:
mvn spring-boot:runThe app starts on http://localhost:8080, with 3 sample stock rows pre-loaded on startup.
Example — test the automatic pharmacy failover with real-time sync and ETA:
curl -X POST "http://localhost:8080/stock/order?medicineName=Paracetamol"Example — run your own load test:
ab -n 100 -c 20 -p empty.txt -T application/json -m POST http://localhost:8080/stock/{id}/orderMost delivery-app clones stop at CRUD (browse, cart, checkout). This project instead focuses on the distributed-systems-style problems that actually come up in backend engineering interviews: race conditions, atomic operations, failover logic, and event-driven sync — implemented, tested, and benchmarked under concurrent load, not just described.