Running a guest list when the replies arrive in every direction at once
A guest list looks like a simple thing to keep. It is a list of people. In practice it is a list of answers that turn up over three months by text, by post, by a shout across a car park, and each one quietly changes a number somebody else is waiting for. This article walks through how the tracker models a guest list, why a household is not the same as a person, why covers are not the same as names, and how the two printed sheets are put together.
Adding up the sample wedding: 15 covers today, 26 in the worst case
Every figure on the page comes from one walk down the guest rows. Each row is dropped into one of three piles by its reply: yes, no, or still waiting. The covers on a row are the adults plus the children on that row. Which pile the row falls into decides which running total those covers join.
The sample list that loads on a first visit is a good way to check the sums by hand. It holds 15 rows across 13 party names. Thirteen of those rows have had an invitation; two have not. Eight said yes, one said no, and six have not answered. The eight accepted rows carry 12 adults and 3 children between them. That is where the 15 confirmed covers at the top of the page comes from.
The reply rate divides replies by invitations, not by rows. Eight yes and one no make nine replies. Nine out of thirteen is 69.2 percent, which is shown as 69 after rounding to a whole number. The two rows whose invitations have not gone out stay out of that sum on purpose. Those two are waiting on you, not the other way round.
The six silent rows are worth 11 covers between them. Add those to the 15 already promised and the worst case is 26. Capacity in the sample is set to 120, so 15 confirmed leaves 105 seats free, and even 26 is nowhere near the edge. Set the capacity box to 20 instead and a warning appears straight away. You are inside it today, but six covers over if every outstanding reply came back yes. That six is 26 minus 20.
The money line is a single multiplication. Cost per cover starts at 46 in pounds, so 15 covers reads as 690.00 pounds. It follows whichever of the thirteen currencies you pick. Twelve of them print two decimal places. The Japanese yen prints none, because it has no minor unit, and two decimals there would make the figure look a hundred times too small.
The chase window starts at 21 days. Waiting time is the whole number of days from the invitation date to today, worked out in UTC so that a clock change in spring or autumn cannot shift it by a day. In the sample, Ruth and Callum were invited 38 days ago, Eleanor 33 days ago, and Nora 12. Four people sit on the chase list, and three of them are past 21 days, so the red counter reads three.
Meal covers are counted for accepted rows only, and children move onto their own line while the separate children's menu setting is ticked. Priya's row is one row, but it splits two ways: two adults on Chicken, and two children on the children's menu.
- Chicken, 5 covers, 33 percent: two adults from Priya's row, two from Yusuf, one from Bill.
- Sea bass, 4 covers, 27 percent: Gerald, Margaret, and the two on Hannah's row.
- Children's menu, 3 covers, 20 percent: Priya's two children and Ade's one.
- Mushroom wellington, 3 covers, 20 percent: two adults from Ade's row, one from Dev.
- The meal lines add back to 15, matching the covers counter exactly.
- Seating at 8 seats a table: table 1 holds 7 covers with 1 spare, table 2 holds 5 with 3 spare, table 4 holds 3 with 5 spare.
Rounding, spelling, and the places this list will let you down
Head counts are whole people. Whatever you type in the adults or children box is rounded to the nearest whole number, and anything below zero is pulled up to zero. Type 1.5 adults and the row holds 2. The same rounding is applied to venue capacity, seats per table, and the chase window. Cost per cover is the one exception. It keeps its decimals, but it too cannot go below zero.
Meal names and table names are matched in two different ways, and that catches people out. A meal name has its spaces trimmed and is then matched exactly, capital letters and all. Chicken and chicken end up as two separate lines on the caterer sheet. Table names are lowered first, so Top table and top table are treated as the same table. This is why the meal box offers a drop-down of the options you set: choosing from it keeps the spelling identical every time.
Shares in the meal table are each rounded to a whole percent, while the total row always prints 100%. On some lists that column will add to 99 or 101 instead. The covers column is the one to trust. The percentages are there to read, not to add up.
The party counter keys on the party text exactly as typed, with no trimming. A stray space at the end of one entry makes it count as a second party, even though the filter list above shows a single name. If the party figure looks one too high, that is the first thing to check.
Imported dates are read in a fixed order. A plain 2026-06-14 is taken at face value. A slashed date is settled by its numbers where it can be: if one of the first two is above 12, that one has to be the day. When both are 12 or under there is no way to tell, so the date format chosen in the rail decides. Two-digit years use a fixed pivot: 71 through 99 become 1900s, and 00 through 70 become 2000s, so 70 reads as 2070. Written months are matched on their first three letters, so Sept and September both land on September. Anything else is left blank and counted in the message at the end of the import, rather than guessed at.
Column headings are stripped of everything that is not a letter or a digit and then lowered before matching. The first recognised spelling wins, and once a column has been claimed no other field can take it. That leaves one trap worth knowing about. A column headed Seats is read as a count of adults, because the adults field claims that word before the table field is offered it. Rename it Table number if a seating plan is what you meant.
Tick columns are read generously. A blank cell is a no. Otherwise the cell is a no only when it holds one of the recognised negatives, such as no, n, false, 0, declined, or regrets. Any other text at all, maybe included, is read as a yes.
- There is one rate per cover. Children are charged at the adult rate in the money figure, even while they sit on their own menu line.
- A row carries one meal choice. Two people on a row who want different mains need two rows.
- The over-capacity alarm compares confirmed covers with capacity. The worst case is shown beside it and warned about, but it is never treated as a booked number.
- A guest with no invitation date is never marked overdue. The waiting column reads unknown instead, because there is nothing to subtract from.
- Waiting days are measured against this device's clock. A wrong system date moves the whole chase list with it.
- The dietary chip counts accepted guests who have a note, but clicking it filters to every guest with a note, whether they have accepted or not.
- An import never deletes anything. Rows are matched on the guest name ignoring capitals, so a corrected spelling adds a second row instead of updating the first.
- Drinks, deposits, service charges and room hire are not modelled at all. The catering figure is covers times one rate, and nothing else.
Why the spreadsheet always drifts
Most people start a guest list in a spreadsheet, and for the first fortnight it works. Then the replies start. One arrives as a reply card in the post. One comes as a text at eleven at night. One is a message from your mother saying that your aunt is coming but is bringing your cousin, who is fifteen, and does that count as a child.
Each of those changes at least three figures: how many people are coming, how many meals to order, and how many seats are left. A spreadsheet will happily hold all of it, but it will not add anything up unless you write the formulas yourself, and nobody writes the formula for how many replies are still outstanding after a fortnight of doing this in the evening.
So the spreadsheet drifts. The venue asks for a number and you count the yes column by eye. Three weeks later you find two rows you never updated. This tool exists because those three figures should never need counting by hand at all.
Names and covers are two different totals
The single most useful idea in the whole tool is that a guest list has two sizes, and confusing them causes most of the trouble.
The first size is names: how many people you write to, chase, and eventually thank. The second is covers: how many bodies walk through the door, eat a meal and need a chair. Eighty invitations can easily be a hundred and forty covers once partners and children are added.
You care about names. The venue and the caterer care about covers. Every counter on the dashboard reports both, and the labels say which is which. Where a figure could be read either way, it is spelled out rather than left to guesswork.
This is also why the adults and children boxes sit on every row. A row is not always one person. It is one reply, and one reply can bring four people with it.
One row per reply, grouped into parties
The rule for adding rows is simple. Give a row to each person or group who will answer you separately.
A married couple who reply together in one message are one row with two adults. Two friends who share a flat but each answer for themselves are two rows. A family of four who reply as a family are one row with two adults and two children.
The party field then puts those rows back together. Everyone under the same party name is treated as one household for grouping and for the printed sheets. So the two flatmates can be two rows for chasing purposes and still appear side by side on the check-in sheet under one heading.
There is one honest limit to this. A row carries a single meal choice. If two people share a row and want different mains, split them into two rows with the same party name. Nothing is lost by doing that, and the caterer summary then tells the truth.
Set the event up before you type a name
The rail on the right holds the things that apply to the whole event rather than to any one guest. It is worth five minutes at the start.
The event name and date are printed at the top of both sheets, so the caterer knows which job the page belongs to. The venue capacity drives the warning that matters most, which is covered further down. Seats per table drives the spare seats column in the table plan.
The meal options box takes a comma separated list. Whatever you type there becomes the suggestion list on every guest row. This is not decoration. If one person types Sea bass and another types sea bass with lemon, the caterer summary splits into two near-identical lines and neither total is right. Picking from a list keeps the wording identical.
The date format setting changes every date on screen, on the sheets and in the exports. Choose the one your caterer and your venue use. Nothing is more annoying than an order sheet that says 12/03 when everyone involved means March the twelfth and the kitchen reads it as December.
What invited actually means
There are two separate pieces of information about an invitation, and mixing them causes false alarms.
The first is whether it has gone out at all. That is the tick box. The second is when it went out. That is the date, and it is optional.
Ticking the box fills in today for you if the date is empty, because ticking it is a statement about now. Unticking the box leaves the date alone, in case the tick was a slip and you want it back.
The date is what the waiting counter subtracts from. A guest with no date shows on the chase list with waiting time unknown rather than as overdue. That is deliberate. An imported spreadsheet often has a yes or no column and no date at all, and inventing a date to make the arithmetic work would put people on an overdue list on the strength of evidence that does not exist.
Awaiting is a real answer, and it has a cost
Silence is not a no. It is also not a yes. It is its own state, and every figure that depends on it says so.
Guests who have not replied are never added to the confirmed covers and never added to the declines. They sit in their own bucket with their own counter. The caterer summary quotes confirmed covers as a floor and names how many replies are still out, so the kitchen knows the number can only go up.
The number worth watching is the projected total: what the headcount becomes if every outstanding reply comes back yes. It sits next to the capacity figure. Being comfortably inside capacity today means nothing if the twelve people who have not answered would push you eleven over.
This is the warning that saves a phone call to the venue at the wrong moment. It appears while you can still do something about it, which is usually a fortnight before it would have surfaced on its own.
Chasing people without becoming a nuisance
The chase list shows everyone who has been invited and has not answered, longest wait first. It is deliberately not a list of everybody who has not replied, because people whose invitations have not gone out yet are your problem, not theirs.
The chase-after setting decides when a wait turns from black to red. Three weeks is a reasonable default for a wedding. A work event with a fixed deadline might want ten days.
Two buttons sit on each row. If somebody answers on the phone, one click records it and the row leaves the list immediately, with the reply date filled in. That is the whole point: the moment between hearing an answer and losing it is short, and a form that takes six clicks is a form you skip.
The copy button puts the outstanding names, contacts and waiting times on the clipboard as plain text. Paste it into a group message, a note to your partner, or an email to whoever is doing the phoning.
Meals, children and the dietary list
Covers by meal choice is the figure a caterer asks for, and it is a little more subtle than it looks.
Children are usually priced and served differently from adults. So there is a setting for it. When the children take the children's menu option is ticked, the children on a row are counted on the children's menu line rather than on whatever the adults chose. Untick it and everyone on the row counts towards the same meal. Either behaviour is defensible; leaving it unstated is not, so the caterer sheet prints a sentence saying which one was used.
Guests who have accepted but have no meal recorded appear on their own line as no choice recorded, and the dashboard warns you how many covers are missing. Nothing is quietly rounded into the most popular option.
The dietary list is separate and specific. Every accepted guest with a note appears with their table number, so a kitchen knows not just that one gluten-free main is needed but which table it goes to. That is the difference between a note and a usable instruction.
Seating and the spare seat problem
The table field takes any text at all. Numbers are the obvious choice, but Top table, Oak Room and Marquee left all work, and they sort sensibly next to each other.
The table plan totals the covers on each table and, if you have set the seats per table figure, shows how many seats are still free. A table holding more covers than it has seats is flagged in red. This catches the classic mistake of moving a family of four onto a table that already had six people on it.
Accepted guests with no table yet are gathered into their own row so you can see at a glance how much seating work is left. The dashboard has a chip for the same thing, which filters the list down to exactly those people in one click.
Seating tends to be done in one long evening near the end. Being able to filter to unseated guests, assign a few, and watch the spare seats column move is the fastest way through it.
Bringing in the list you already started
Almost nobody starts here. Most people arrive with a spreadsheet that is half done, and the import is built for that.
Drop a CSV on the import panel and the columns are matched by name. Around sixty headings are recognised, because people write the same thing in a dozen ways: guest, name, attendee, invitee for the name column; household, family, party, invite group for the grouping; dietary requirements, allergies, special diet for the notes. A first name and last name pair is joined if there is no single name column.
The reply column is read loosely on purpose. Yes, y, attending, accepted, coming, confirmed and 1 all mean yes. No, n, declined, regrets, not attending and 0 mean no. Anything else, including a blank, is treated as still awaiting, which is the safe reading.
Rows are matched on the guest name. A name already on the list is updated in place and a new name is added. Nothing is ever deleted by an import, so a second pass with a corrected file fixes rows rather than duplicating them. Dates that cannot be read are left blank and counted in the message at the end, rather than being guessed at.
The two sheets, and why they are on paper
On the day, nobody is looking at a screen. Somebody is standing at a door with a clipboard, and somebody else is in a kitchen with a sheet taped to a wall.
The check-in sheet lists accepted guests with a tick box each, their party, adults and children, meal, table and any note. It can be grouped by table, grouped by party, or run as one alphabetical list. A door works best alphabetically; a seated dinner works best by table. At the bottom there is a line for who did the checking in and how many covers actually turned up.
The caterer summary is the other half: covers by meal, the sentence about how children were counted, the dietary list with table numbers, and covers by table with the meal breakdown for each. If you have set a cost per cover, it also carries the total at today's count, which is a useful sanity check against a quote.
Both sheets follow whatever filters are set on the guest list. Filter to one table and print, and you get that table only. Filter to a category and print, and you get that group. The sheets are not a separate report to configure; they are the list you are already looking at, on paper.
Gifts, thank-yous and the fortnight afterwards
The part everybody forgets is the fortnight after the event, when the thank-you notes are supposed to be written and nobody can remember who gave what.
The gift box takes a short description of whatever arrived. Leave it blank if nothing has. The thank-you tick records that the note has been written, and the dashboard counts how many are still owed.
It is a small feature and it takes ten seconds per guest, but it is the only record most people will ever have of it. Writing the description as the parcel is opened is far easier than reconstructing it from memory in three weeks.
Where the list lives
A guest list is a pile of names, phone numbers, email addresses, allergies and children. It is exactly the sort of information that should not be sitting on somebody else's server for the sake of a headcount.
So it does not go anywhere. Everything is held in this browser's own local storage, on this device. There is no account, no sign-in and no upload. Close the tab and reopen it and your list is still there. Open the same page on a different computer and it will be empty, because nothing was synced.
That last point is worth repeating, because it is the one trade-off. The list is tied to this browser. Clearing your browsing data will remove it. The backup button writes the entire list to a JSON file that you keep, and the CSV export gives you a copy that opens in any spreadsheet. Take one of those before you clear anything, and keep it somewhere you will find it.
