Software · 01 / 06 · Java · Spring Boot · React
Showtime: Event Ticketing
A BookMyShow-style ticketing app with live seat maps, where a seat is never sold twice however many people go for it at once.
- Java 25
- Spring Boot 4
- PostgreSQL
- React
- TypeScript
- Server-Sent Events
- k6
- Playwright
Why I built this
When a big concert or an IPL final goes on sale, thousands of people click the same seats in the same second. If two of them both get a confirmation, one turns up at the venue to find someone in their seat, and the ticketing company eats the refund and the anger.
How do you let thousands of people grab seats at the same moment without ever selling one twice, and still show everyone the seat map changing live? I wanted to build the full app, Java backend to React frontend, and then stampede it.
What I built
A full ticketing app: browse events, pick seats on a live seat map, hold them for ten minutes, pay, get a booking. Spring Boot with JWT auth and roles on the backend, React and TypeScript on the front.
Seats are rows in PostgreSQL. Holding locks them with FOR UPDATE SKIP LOCKED, so two buyers racing get an instant yes and an instant no. Payment is confirmed by an HMAC-signed webhook, processed exactly once, and every browser on either server sees seats change as they happen.
How it works
Each API instance LISTENs to PostgreSQL, so a seat taken through one server shows up instantly for buyers connected to the other.
How it stays correct
Seat status lives on one row with check constraints; holds lock with SKIP LOCKED and never wait.
An expired hold counts as free everywhere, so correctness never depends on a background job.
Webhooks are HMAC-verified and deduplicated by event id in the same transaction as the booking.
pg_notify to LISTEN on each instance, then Server-Sent Events to each browser.
Measured
- Rush
- 200 buyers for 60 s at one 1,000-seat event: 59,119 hold attempts, 424 bookings
- Audit
- 0 seats sold twice; 50 buyers racing for one seat got exactly 1 hold
- Webhooks
- The same webhook sent 5 times at once created 1 booking
- Tests
- 24 integration tests (95.6% lines), 25 web tests, Playwright races 18/18