Seat-Selection Service
Core backend services for seat selection on a large-scale ticketing platform — designed for correctness under heavy contention, horizontal scale and extensibility across venues and seat-map rules.
The challenge
Seat selection becomes a distributed-systems problem during high-demand events: many buyers can request the same limited inventory at nearly the same moment, while the platform must respond quickly, preserve a single source of truth and never allow the same seat to be held by two buyers.
What I worked on
I designed and implemented core backend components for seat availability and reservation using Java and Spring Boot. The service was structured around stateless APIs, a contention-safe reservation path, durable seat state and event-driven integration so new venue layouts and business rules could be introduced without rewriting the core flow.
- Built REST APIs and domain services for seat availability, hold and reservation workflows.
- Designed concurrency handling around atomic conditional updates so competing requests could not acquire the same seat.
- Integrated Kafka for asynchronous seat-state events and downstream processing outside the critical request path.
- Modelled venue, section, row, seat and reservation rules in an extensible domain layer.
- Added JUnit and contention-focused tests that exercised simultaneous requests against the same inventory.
- Packaged the services for containerized deployment and horizontal scaling on Kubernetes.
Concurrency & consistency
The critical path is the seat hold. A request first validates the seat and reservation rules, then attempts an atomic conditional state change in the persistence layer. Only one competing request can transition an available seat into a held state; losing requests receive a conflict rather than overwriting the winner.
- Conditional compare-and-set style writes protect the seat state under contention.
- Short-lived holds use an expiry/TTL model so abandoned reservations return to inventory automatically.
- Idempotency at the API/service boundary makes retries safe when clients or upstream services repeat requests.
- The synchronous reservation decision stays on the request path; non-critical follow-up work is emitted asynchronously.
Event-driven flow
After a successful state transition, the service publishes reservation events to Kafka. Downstream consumers can react to events such as a seat being held, confirmed, released or expired without coupling those workflows to the latency-sensitive reservation API.
This keeps the source-of-truth reservation decision separate from asynchronous processing and avoids treating Kafka itself as the locking mechanism.
Failure handling
- Conflicting reservation attempts fail cleanly instead of silently overwriting seat state.
- Retryable operations are designed to be idempotent so network retries do not create duplicate reservations.
- Expired holds are recoverable without manual cleanup, preventing inventory from remaining locked indefinitely.
- Consumers can be retried independently from the user-facing API, isolating downstream failures from the booking path.
Testing for the hard case
The most important tests were not simple CRUD tests. They exercised many simultaneous requests against the same seat or small inventory set and verified that one request could win while every competing request observed a deterministic conflict. Additional tests covered retries, expiry and event-processing behavior.
Impact
The service shipped into production and supported seat-selection workflows at large scale. The design emphasized correctness first, then horizontal scalability and extensibility so the platform could support new venues, seat maps and reservation rules without rebuilding the core reservation path.