GS.Let's talk
← All workEvent Registration
Case study

Event Registration

A fair registration system for ~700 people chasing 500 seats — first to arrive, not fastest to type.

Event RegistrationInteractive demo · sample data

What it is

The sign-up site for a youth retreat: a countdown, a 4-step form with autosave, then a payment code and PayPal checkout. It is built for the moment registration opens and about twice as many people as there are seats arrive at once.

Why I built it

Fairness was the whole brief: your place should depend on when you arrived, not how fast you can type, and everyone who gets a ticket should be able to finish their form. We expected around 700 people for 500 seats — on several devices, refreshing constantly — so it also had to never sell more seats than exist.

700people tested for 500 seats
500seats sold — never more
15 minto finish the form
$2252-night registration (CAD)

How it works

A ticket the instant you arrive

Opening the form creates a ticket whose number is the database's auto-increment id. Your position is the count of earlier tickets that are still live, plus one — so when someone times out or is merged, everyone behind moves up.

Refresh-proof, autosaved

A cookie brings back the same ticket after a refresh, and answers autosave 2 seconds after you stop typing. Each ticket gets 15 minutes to finish the form.

Duplicate detection

On submit, the same name plus a matching phone, email or date of birth counts as a duplicate. The person can merge, which keeps the lower (earlier) ticket.

Codes and a database lock

In production everyone received a payment code (church tag + 8 characters) and redeemed it at the same moment. Each redemption runs in one transaction that locks the max_seats settings row with SELECT … FOR UPDATE as a global mutex, counts paying + registered, then either reserves a seat or moves the person to a waitlist ordered by when they tried.

Load-tested

With 700 simultaneous redemptions for 500 seats the result was exactly 500 seats and 200 on the waitlist — never more. An earlier 700-user test report had flagged race conditions under load and recommended SELECT … FOR UPDATE inside a transaction, which is the approach the redemption uses.

Built with

React 18 + VitePython FastAPIMySQLServer-Sent EventsJWTPayPalGmail SMTP