Seat allocation

Sequential seat numbers,
no two attendees ever collide.

Every registration gets the next number in line. VIPs get V-1, V-2, V-3. General gets G-1, G-2, G-3. Assignment runs inside a DB transaction with row-level locks so two people submitting at the same instant never share a seat.

admin/events/summit-2026/seats
Seat map
Product Summit 2026
REMAINING
124
VIP · 8 booked
V-1
V-2
V-3
V-4
V-5
V-6
V-7
V-8
General · 20 booked
G-1
G-2
G-3
G-4
G-5
G-6
G-7
G-8
G-9
G-10
G-11
G-12
G-13
G-14
G-15
G-16
G-17
G-18
G-19
G-20
G-21
G-22
G-23
G-24
G-25
V-8 just booked · Priya Nair · 400ms ago

One transaction. One row lock. One seat.

Under load, the seat table becomes the bottleneck by design. That is exactly what prevents collisions.

🔒
Row-level lockForUpdate
Each assignment opens a DB transaction and locks the count row. Concurrent submissions queue rather than race.
🔢
Sequential, never reused
V-8 stays V-8 forever, even after a cancellation. Retired numbers are auditable, reassignment is impossible.
🏷
Tenant prefixes
Default V and G. Change to PLAT-1 or FLOOR2-A per event. Prefix lives on the event row, not hardcoded.
🎟
VIP tied to coupons
A valid coupon unlocks a V-seat. Max VIP seats equals coupons issued. You never oversell the premium tier.
📉
Live remaining counter
Admin dashboard shows VIP left and General left, updating as bookings land. Hit the cap, registration closes automatically.
400ms typical
Lock, count, insert, commit. On MySQL 8 with a warm buffer pool, most assignments finish in well under half a second.

Form to seat, in four database steps.

1
Attendee submits
Form posts to /register with the event slug and optional coupon code.
2
Lock the count
DB::transaction opens. lockForUpdate on the registrations count for that event and category.
3
Assign next number
Count plus one, prepended with the tenant prefix. VIPs get V-N, general gets G-N.
4
Return seat and QR
Commit. QR image generates. Attendee lands on the confirmation page with pass ready. 400ms typical.

The race condition that got two aunties on the same chair.

A wedding reception in Delhi, 2024. The bride's family had reserved 40 seats in the front two rows for immediate relatives. We were using a rough seat counter that read the row count, incremented by 1, and wrote back. Worked fine for testing.

Actual event day: the bride's mother forwarded the RSVP link to the family WhatsApp group at 11.07am on a Sunday. Six aunties tapped the link within the same second. Three of them got seat number 12. When they showed up at the venue, one of them had to stand for the ceremony. We got yelled at in three languages.

Post-mortem was short. Increment-and-write is a textbook race condition. The fix is a database transaction with a row-level lock so concurrent registrations serialise. We wrapped seat assignment in `DB::transaction` with `lockForUpdate` on the same evening. Never happened again.

Small extra thing we added later: an audit log per seat, showing every attempted assignment and which one won. Makes debugging really easy when a client swears their VIP list is off by one.

A 250-seat awards night with 40 VIP seats.

  1. Setup, 3 minutes. Client creates the event with vip_seat_prefix=V, general_seat_prefix=G, max_vip_seats=40, max_general_seats=210. Registration opens.
  2. Registration flow. Attendee fills the form, hits submit. On the server, `DB::transaction` opens. `lockForUpdate` grabs the seat row for this event+category. Count = 6. New seat = V-7. Row committed. QR image queued for generation.
  3. Total latency. Registration form submit to confirmation page render: 400ms median, 900ms 95th percentile. Attendee never sees the lock happen.
  4. Concurrent load. A promo link posted to a 4,000-member Telegram group. In the first 60 seconds, 87 registrations arrive. Each waits for the lock, gets its seat, releases. No duplicates. VIP hits its 40-cap at second 34, remaining VIP requests get "VIP sold out" and are offered General instead.
  5. Cap reached. Once max_general_seats hits 210 (about 12 minutes later), the landing page auto-flips to Sold Out. Registration is closed at the model layer, not just the UI, so nobody can slip through by re-posting the form.
  6. Attendee experience. V-7 is printed on the branded pass. Same number appears on the badge printed at the kiosk. Same number in the concierge Excel export. One source of truth.

Zero shared seats across 12,000+ registrations we've run on this system.

Seat management tools compared honestly.

For a 500-seat ticketed event, one day, India 2026.

ToolModel / CostNotesVerdict
BookMyShow venue tool10-12% ticket feeSeat map picker. B2C-focused, hard to white-label.Good for public shows
Cvent Session Seat AssignmentEnterprise add-onPowerful. Sold in the base Cvent package (₹5L+ per year).Overkill for most Indian MICE
Google Sheets + manualFree + your SaturdayWorks for 50 seats, breaks at 200. Duplicates guaranteed.Zero until it isn't
SignupDesk seat allocatorIncludedDB-level locking. Custom prefixes per event. Auto Sold Out.Duplicate-proof by design

Vendor prices vary by region and negotiated discount. Ours is included in the platform fee.

Modules that read the seat number.

🎨
Seat number renders on every pass in the biggest weight on the card. V-7 or G-142, front and centre where the concierge can spot it.
🖨️
Same seat number prints on the physical badge at the kiosk. What guests see on their phone matches what's pinned to their lapel.
📊
Sort or filter registrations by seat number for concierge desks who work "by row". Also exports cleanly to Excel.

Questions we get

Can two attendees share a seat?
No. Assignment runs inside a DB transaction with row-level lockForUpdate. Concurrent registrations serialise. Numbers are always unique and sequential.
Custom seat prefixes?
Yes. Each event stores vip_seat_prefix and general_seat_prefix. Default V and G, change to anything per event.
Assigned or open seating?
Works for both. Print V-7 on the pass for assigned seating, or use it as entry order for open seating.
What if I hit the cap?
Registration closes automatically once the max seats for that category are booked. The landing page shows a Sold Out state.
Never oversell a seat again.
Free demo on your event data. See a concurrent registration test live.