Seat maps and reserved seating
Reserved seating looks like a design feature and is really a concurrency problem wearing a floor plan. Everything difficult about it happens in the last ninety seconds of a popular on-sale, when more people want a particular seat than there are copies of that seat — which is to say, one.
A seat is held, not reserved forever
When a buyer picks a seat, it is held for 15 minutes. That number is a compromise between two failure modes, and it is worth understanding both.
Too short, and real buyers lose their seats mid-checkout — hunting for a card, being interrupted, reading your refund policy properly. Nothing makes a person abandon a purchase faster than being told the seat they were about to pay for is gone. Too long, and every abandoned basket takes a seat out of sale for the evening. Fifteen minutes is comfortably longer than a card payment including a 3-D Secure step, and short enough that a browser tab closed at 19:00 is not still holding row F at 19:45.
If checkout is not completed, the hold expires and the seat returns to sale automatically. Nobody has to notice, and no cleanup job has to be running for the common case to work.
Two people, one seat
This is the whole problem. The hold is taken atomically: exactly one session can claim a given seat, and the second request is refused immediately rather than queued behind the first. There is no window in which both requests have looked at the seat, both found it free, and both proceeded.
It matters most in exactly the case where it is hardest — the last few seats, everyone clicking at once — which is precisely when a naive implementation double-sells. The naive implementation is not obviously wrong when you read it, and it passes every test written by one person clicking one button. It fails in front of an audience.
The visible consequence of getting this right is that a buyer sometimes sees "that seat has just gone". That is the correct outcome. The alternative is two people with a receipt for the same chair, and one of them finding out at the door.
Holds survive a restart
Holds live in the fast in-memory store and in the database. The in-memory copy is what makes the seat map responsive; the database copy is what means a restart, a deployment or a crashed process does not silently free every held seat in the middle of your on-sale.
This is a deliberate cost. Writing every hold twice is more work than writing it once, and the payoff only shows up on the worst day.
Mixing seated and general admission
You can sell numbered seats and general-admission tickets for the same event, which is the normal shape for a venue with a seated stalls and a standing floor. General admission has no seat to hold, so its availability is counted against the ticket type's own quantity instead — the same inventory mechanism as any unseated event.
Both kinds of ticket end up in the same booking, the same confirmation email, the same PDF and the same door list. Your staff do not need to know which is which; the scanner does.
Reading your sales figures during an on-sale
One consequence worth planning for: a held seat is not a sold seat. Your sales figures count confirmed bookings. During a busy on-sale, the seat map will therefore show more seats visually locked than your revenue figure accounts for.
That gap is not an error and it closes on its own as holds expire or convert. The mistake to avoid is reacting to it — releasing extra inventory at 10:03 because the map "looks sold out" and the money does not match. Wait fifteen minutes and look again.
Practical advice for a seated on-sale
- Do not open the map for the first time on the day of the on-sale. Check it against the room while you can still change it.
- Decide about holdbacks in advance. Seats for guests, press, wheelchair companions and the sound desk are much easier to withhold before sale than to recover after.
- Expect the last ten per cent to be slow. Single leftover seats between sold pairs sell last, everywhere, always. That is a property of how people buy in groups, not of your pricing.
If your event is unseated, none of this applies to you and you should not enable it. A seat map on an event that does not have assigned seats is a support burden with no upside.