Part 1 of 7 · Event RSVP manager series ~5 min read

An event RSVP manager on AWS for a few dollars a month

Running the guest list for a small event is more fiddly than it looks. The room holds 80 and you must not let 95 people show up. Three people RSVP for the last two seats in the same minute. Two days out, half the “yes” crowd has forgotten the time. Someone cancels the night before and the seat just sits empty while ten people would have gladly taken it. This post walks through the design of a small manager that runs all of that: it confirms each RSVP, reminds people at the right time, handles cancellations cleanly, offers freed seats to a waitlist, and never lets the event oversell.

Key takeaways

  • Three outside pieces: a register form, the event setup, and the guests who get emails.
  • Every guest moves through a few clear states: pending, confirmed, waitlisted, cancelled.
  • The capacity cap is enforced by the database, so the event can never oversell.
  • Reminders and waitlist offers respect quiet hours and the host’s settings.
  • Designed on AWS for about $2.40 for a typical 200-guest event.

The whole system on one page

Before any code, here’s the shape of what we’re designing.

System architecture: three pieces outside, three inside AWS At the top, three external boxes in a row. Far left, "Register form" — a simple web form where people enter their name and email to ask for a seat; it also feeds two side lanes covered later, an email reply-to lane and a host bulk-import lane that add people to the list. Centre, "Event setup" — the host's settings: the event name, date and time, the capacity cap, the reminder schedule, the quiet-hours window, and the waitlist claim window. Far right, "Guests" — the people on the list; confirmations, reminders, and waitlist offers land in their email inbox. Each connects via an arrow to the AWS account container below. The register form has an outgoing arrow into AWS. Event setup feeds in to shape every message and the cap. Guests receive emails with the event details, a confirm or cancel link, and for waitlist offers a claim link with a deadline. Inside the AWS account are three components in a row, mirroring the layout above. On the left, the Register intake — receives a sign-up, checks for duplicates, and either confirms a seat or places the person on the waitlist. In the middle, the Guest-list keeper — holds every guest's state, enforces the capacity cap with a single conditional write, and decides what happens on a confirm, cancel, or claim. On the right, the Messenger — sends the confirmation, the reminders, and the waitlist offers, respecting quiet hours and the host's schedule. Internal arrows flow left to right. A note at the bottom reads: the cap is the one number the whole system defends — the event never oversells. Register form form, email, import Event setup cap, schedule, quiet hours Guests where emails land sign-ups shapes email with a link AWS account Register intake take sign-up, seat or waitlist Guest-list keeper holds every state, defends the capacity cap Messenger confirms, reminds, respects quiet hours guest send The cap is the one number the whole system defends — the event never oversells.
Fig 1. Three pieces outside, three pieces inside AWS. Sign-ups flow in from a register form, an email reply lane, and a host import. The Guest-list keeper holds every guest’s state and defends the cap. The Messenger sends the right email to the right person at the right time.

What you set up once (the outside)

  • The register form. A simple web page where people enter their name and email to ask for a seat. It can live anywhere — a page on your site, a link in a flyer, a QR code at the door. The form posts to the system, which then either confirms a seat (if there’s room) or places the person on the waitlist (if the event is full). Two other lanes can also add people, covered in Part 2 — an email reply lane (someone replies “yes” to your invite and the system reads it) and a host import lane (the host pastes a list of names the system signs up in bulk).
  • The event setup. A short set of host settings. The event name, date and time, and venue. The capacity cap — the single most important number, the most confirmed guests the room can hold. The reminder schedule — how far ahead to remind people (a week out, a day out, the morning of). The quiet-hours window so no reminder lands at 2am. And the waitlist claim window — how long a freed seat is held for the next person before it rolls on. None of these need a developer to change; they live in a settings record the host can edit.
  • The guests. The people on the list. Each one has a name, an email, and a state: pending (signed up, not yet confirmed), confirmed (holds a seat), waitlisted (in line for a seat), or cancelled. Emails land with the event details, a confirm or cancel link, and — for a waitlist offer — a claim link with a clear deadline. No app to install; everything happens in the inbox.

What runs inside (the system)

  • The register intake. Takes a sign-up from any of the three lanes. Checks whether this email is already on the list (so nobody double-books). Then asks the guest-list keeper for a seat. If a seat is granted, the messenger sends a confirmation. If the event is full, the person is placed on the waitlist and told their position. Simple, deterministic, no guesswork.
  • The guest-list keeper. Holds the state of every guest and the live confirmed count. This is where the capacity cap is enforced: a seat is claimed by a single conditional write — a database update that only succeeds if the confirmed count is still below the cap. Two people racing for the last seat can’t both win; the database lets exactly one through and refuses the other. The keeper also decides what happens on a cancel (release the seat, start the waitlist offer) and on a claim (move a waitlisted guest into a confirmed seat).
  • The messenger. Sends every email: the confirmation when a seat is granted, the reminders on the host’s schedule, the waitlist offer when a seat frees up, and the post-event thank-you. It reads the quiet-hours window and never sends a reminder overnight — a message that would land in the quiet window is held until the next morning. Every email is recorded so the system knows what already went out and never sends a duplicate.

In plain words

Your workshop seats 40. The form goes live and 38 people confirm over a week; each one gets a clean confirmation email the moment they click. Two days out, everyone who confirmed gets a friendly reminder with the time and address — sent at 9am, never overnight. The night before, two people cancel with one click. Each freed seat is immediately offered to the first person on the waitlist with a link that holds the seat for six hours. The first waitlister claims theirs in twenty minutes; the second never opens the email, so at the six-hour mark the offer rolls on to the next person in line, who claims it the next morning. On the day, the room has exactly 40 confirmed guests — not 38, not 42 — and the host never touched a spreadsheet.

The cost of running this is about $2.40 for a 200-guest event. The cost of not running it is the overbooked room you have to turn people away from, or the half-empty room because cancellations were never back-filled, or the no-shows who simply forgot the time.

Design rules that shaped every decision

  • The cap is sacred. A seat is claimed by one conditional write; the event can never oversell, even under a race.
  • A freed seat is offered, not given. The waitlist gets a timed claim link; a stale offer rolls on, never blocks the seat.
  • Quiet hours are respected. A reminder that would land overnight waits until morning.
  • Every email is logged. The system never sends the same reminder twice.
  • The host settings live in one record — change the cap or the schedule without a deploy.
  • Every state change is recorded. After the event, the guest list is fully reconstructable.

Why this shape

Most small events are run on one of three things: a spreadsheet someone updates by hand, a free form tool that emails you raw responses, or a calendar invite with a headcount nobody trusts. The spreadsheet oversells the moment two people fill the last seat before anyone refreshes. The form tool has no concept of a cap, a waitlist, or a reminder — it just collects rows. And the calendar invite tells you who said yes three weeks ago, not who’s actually coming.

The setup above keeps the simple parts simple — a form, an inbox, a settings record — but adds a small system that defends the cap, fills cancellations automatically, and reminds people at the right time. It never oversells because the database won’t let it. It never leaves a freed seat empty because the waitlist offer fires the moment a cancellation lands. And it never pings someone at midnight. The host sees a live headcount and otherwise leaves it alone.

The next four posts walk through each piece in turn: how an RSVP gets confirmed, how a reminder gets scheduled, how a cancellation frees a spot, and how that freed spot finds the next guest. One diagram per post. A cost breakdown and a final engineering reference at the end.

All posts