Why We Delay Salon Waitlist Notifications by Five Minutes

Product Alex Dunn 4 min read April 7, 2026
Why We Delay Salon Waitlist Notifications by Five Minutes

We almost built the waitlist the way everyone else builds it. A client cancels, the server fires an email to the next person on the list, and the salon crosses its fingers that someone clicks fast enough to rebook. That was the design on the whiteboard for about two weeks. Then we started testing it on real schedules and broke it within an afternoon.

The problem was obvious once we saw it: cancellations do not happen one at a time. A stylist opens her calendar and clears three appointments at once because she is going home sick. A schedule gets moved because a supplier is running late. Every one of those events fired its own notification, and clients on the waitlist got three or four identical emails in under a minute, each linking to a different single slot.

That is the part of the story worth telling. The fix turned out to be a delay.

The alternatives we considered

There were three options on the table.

The first was the industry default: send immediately. This is what Boulevard, Booksy, and most of the big platforms advertise as a selling point. Real-time alerts, instant notifications, the first to respond gets the slot. It reads well in a marketing page. It falls apart when a single schedule change frees up four hours of openings at once, because now every client on the matching waitlist receives four emails in ninety seconds.

The second was a hard schedule: send once a day, at a fixed time. Clean, predictable, kind on the inbox. Also slow enough that a same-day cancellation would be useless, which was the whole point of the feature. The waitlist exists to fill tomorrow morning’s balayage slot that opened up tonight. A daily digest would miss that entirely.

The third was what we shipped: a short debounce window. Cancellations, reschedules, and schedule expansions all get written into a pending slots table. A single batch job is scheduled per tenant with a singletonKey that collapses any new freed slots into the same run. When the batch finally fires, it consolidates everything into one email per client, grouped by date.

5 minutes Default delay before a waitlist batch sends Configurable per salon from 30 seconds to 30 minutes

Five minutes is the default. A salon can drop it to thirty seconds if they run a walk-in heavy shop, or push it to thirty minutes for a chronically over-messaged clientele. We picked five because it was long enough to catch the cluster-cancellation case in our test data and short enough that a same-day freed slot still felt responsive.

How the batched waitlist notification works

The mechanics are simple once you see them. Every time a slot frees up, the server writes a row into a pending slots table and schedules a batch job. If another slot frees up within the delay window, the singleton key reuses the already-scheduled job instead of spawning a new one. When the batch runs, it matches every pending slot against active waitlist entries and sends one email per matched client covering all the freed dates at once.

The consolidation is the part we underestimated. We thought the win was “fewer emails.” It was. The deeper win was that a client who got one email with four openings had a much easier time picking one than a client who got four emails and had to merge them in her head. One message, multiple dates, one decision.

💡 Why consolidation matters more than speed

Salon clients are not watching their inbox for waitlist alerts. They check it twice a day, on their lunch break and after work. Getting there first does not help if the message is buried in three duplicates from the same salon.

We also added one constraint that mattered more than the delay: the batch drops any slot that has already been rebooked or passed. Without that, a client who checked their email an hour later could click through to an offer that was already gone, which is worse than not getting the email in the first place.

What we got wrong on the first pass

We shipped batching before we thought hard enough about schedule changes. The first version only debounced cancellations. A stylist who extended her hours by two afternoons the following week still triggered a flood, because schedule expansions were on a different code path. The fix took another week: synthetic pending slots for each newly covered time block, routed through the same batch job and the same singleton.

Building this again, the lesson would be that the batch is the primitive. Every event type that can free a slot should feed the same pipeline from day one. Piping cancellations through one flow and schedule changes through another looks fine in isolation and breaks the second you combine them.

The other thing we learned: salon owners care less about “how fast” and more about “how often.” The feedback after turning on batching was almost never about timing. It was about the fact that their clients stopped asking why they got four emails in a row. If you want to see how the batch fits into the rest of the system, read our notes on a working cancellation policy and the broader waitlist automation.

Alex Dunn
Alex Dunn

Product at Lutily. Writes from inside the company about what we're building and why.