resources / guides

how to prevent double bookings when you sell on WhatsApp.

To prevent double bookings, check availability and take the date in a single step, include setup and travel in the blocked time, and make holds expire on their own. This guide is for businesses that book over chat. In heysteff, Scheduling (from Starter, 149 USD/month) and Bookings (from Pro, 299 USD/month) handle it.

◆ prerequisites

Knowing how many units (or spots) you really have, how long setup, teardown and travel take, and which booking status you count as "taken".

Why double bookings happen

A double booking is rarely a one-off slip. It is the result of a process with gaps, and the gaps are always the same:

  • Two conversations at the same time. Two customers ask about the same Saturday minutes apart. The two people replying (or the same agent, in two chats) see the date as free and both say yes.
  • A spreadsheet that is out of date. Someone confirmed over the phone and wrote it down later, or never.
  • A quote taken as a booking. The customer got the price and thinks the date is theirs; the team thinks it is not.
  • Incomplete blocks. The calendar shows the event from 8 pm to 1 am, but not the setup time or the trip to the venue.
  • Holds that never end. A date "held while they pay" that nobody releases and nobody collects on either.

Each step in this guide closes one of those gaps.

Step 1: define which statuses take capacity

Before any tool, decide what "taken" means. A clear rule prevents half of all conflicts:

StatusTakes the date?Why
QuotedNoA quote is not a commitment; if it took capacity, a few browsers would block your high season.
HeldYes, with an expiryThe customer has a deadline to pay the deposit.
ConfirmedYesThere is a deposit or the team confirmed it.
CompletedNo (kept as a record)The event is over.
CancelledNoThe date is available again.

Step 2: block the full time, not just the event

If you rent something that has to be delivered and installed, the event is only part of the time the unit is busy. The real block runs from the start minus setup and travel to the end plus teardown. An example with made-up numbers: event A ends at 4:00 pm and teardown takes 30 minutes, so the unit is free at 4:30 pm. Event B starts at 7:00 pm, with 60 minutes of setup and 45 of travel, so the unit has to leave at 5:15 pm. Since 4:30 is before 5:15, the same unit can do both. If B started at 5:30 pm, the unit would have to leave at 3:45 pm, it would overlap with A and you would need another unit.

If the system does not know about setup and travel, it will say "free" while the truck is still at another event.

Step 3: checking and taking must be one step

If availability is checked first and the booking is written later, another conversation can do the same thing in between. Both see the date as free and both take it. It is called a race condition, and with an agent handling several chats at once it happens on any high-season Saturday.

The fix is for checking and taking to happen together and in order: whoever arrives first takes a lock on that unit type (or time slot), checks, writes the booking and releases the lock. Whoever arrives second waits, checks again with the first booking already written, and gets an honest "not available", with alternatives.

Step 4: a last-resort constraint

Locks protect the normal path. But a booking can come in other ways: an import, a manual reassignment, a fix made by the team. That is why a second defense in the database itself is worth having: a rule that rejects two overlapping blocks on the same unit, wherever they come from. If something slips past the first filter, the second one stops it.

Step 5: make holds expire on their own

A hold with no expiry is a slow-motion double booking: the date stays taken, nobody pays and the next customer walks away. Give every hold an expiry time, send a reminder before it expires and release it automatically if the deposit has not arrived, letting the customer know. One important exception: if a payment has already been recorded, the date should never be released automatically; a person should review it.

Step 6: answer "available" or "not available", not how many are left

Telling a customer "we have two booths left" looks transparent, but it causes problems: the number changes within minutes, it invites haggling and it reveals your inventory to competitors. The customer only needs to know whether their date is free and, if not, which nearby dates are.

Step 7: when migrating, flag conflicts instead of hiding them

When you move your events from a spreadsheet or a calendar into a new system, you will probably find days with more events than units: past mistakes nobody had noticed. Do not reject them silently or let them through as if nothing happened. Import them, flag them as conflicts and let the team decide each one.

How heysteff handles it

In the Bookings module, only holds and confirmed bookings take capacity; a quote does not. Each unit's block includes setup, travel (before the event) and teardown. Every write that takes a date (an agent hold, a team booking or an import) takes a lock per unit type and, if you set a daily cap, another per day, and checks capacity inside that lock. Underneath, a database constraint prevents two overlapping blocks on the same unit.

Holds last as long as you configure (48 hours by default), with a reminder before they expire (60 minutes by default) and automatic release; a date with a recorded payment is never released automatically and the team gets an alert. Importing from a heysteff scheduling calendar flags days with more events than units as conflicts.

For timed appointments (a consultation, a visit, a tour with spots), the appointment scheduling module takes a lock per calendar and time slot, rechecks the daily cap and rejects a time that shows as busy in your Google Calendar. To quote without errors, see how to send quotes on WhatsApp with AI.

Frequently asked questions

How do I stop two customers from booking the same date?

By making checking and taking happen in a single step, with a lock per unit type or time slot, and with a database constraint as a second defense. That is how heysteff works in Bookings and in Scheduling.

Should a quote block the date?

No. If a quote took capacity, customers who are only asking would block your best dates. The recommended rule is that only holds with an expiry and confirmed bookings take capacity.

How long should a hold without a deposit last?

As long as your customer needs to make the transfer, without leaving the date taken indefinitely. In heysteff the default is 48 hours, with a reminder 60 minutes before it expires, and both are configurable.

How do I account for setup and travel time between two events?

Block from the event start minus setup and travel to the end plus teardown. Two events can use the same unit only if those blocks do not overlap.

Can I import my current events calendar without losing track of conflicts?

Yes, if your events are in a heysteff scheduling calendar: importing into Bookings rejects nothing and flags days with more events than units as conflicts, so the team can decide.

Which plan do I need and how much does it cost?

Appointment scheduling starts on Starter, at 149 USD/month. The Bookings module starts on Pro, at 299 USD/month, and is also on Max, at 549 USD/month. See pricing.

◆ next step

Stop cross-checking spreadsheets: load your units and let heysteff guard your capacity.

Start free → Get a demo See pricing