#019Everwood BookingLearningIntermediate

A Booking With No Staff Preference Holds Nobody's Time. We Were About to Rank Slots on Top of That.

I asked for research on showing customers better appointment times and got back a clear answer: recommend the good ones, never hide the rest. I agree with it. Then I read our own availability engine and found that the list we would be ranking is not yet a picture of the day. It runs on a fixed half-hour grid anchored to opening time, it keeps five minutes clear after an appointment and nothing before, and when a customer says they do not mind who they see, the booking that results reserves no one.

By the Everwood founder · September 11, 2026 · 12 min read

Tools
SupabasePostgresNext.jsTypeScript
Concepts
Availability ModellingChoice ArchitectureMerchant ControlDefaults as DecisionsResearch Verification
Mission Brief
Goal

Work out whether Everwood should shape which appointment times customers see, and if so whether to rank the good ones, hide the bad ones, or recommend and leave the choice alone.

Problem

I treated it as a scoring and presentation problem on top of the times we already show. Those times sit on a fixed half-hour grid anchored to opening time, carry one fixed gap rule that works on a single side, and do not account for a booking made with no staff preference, which reserves nobody.

Lesson

An availability engine that answers whether a time is free is not a picture of the day. Ranking is a claim about everything the engine never considered, so the list has to describe reality before anything recommends from it.

Read as

The Build

Nothing shipped from this research. There is no ranking, no recommended time, no badge, no gap setting, and no way for a business to change how the times are spaced. The roadmap node this came from is at the idea stage and it is still there.

The problem is real and owners describe it the same way everywhere. A customer books a service in the middle of an open afternoon and leaves two stubs on either side, each too short to sell. Do that three times and the day is full of holes that pay nothing. The business is open, the staff are there, and the money is not.

So the question I went in with was the one the research answers. Should we shape which times customers see, and if so, do we rank the good ones or remove the bad ones?

The research is confident, and I think it is right. Recommend, do not hide. Hiding a valid time is a bet that the customer will take a different one instead of leaving, and it is a bet you place on every customer at once. Ranking makes the same suggestion and keeps the door open behind it.

I was ready to agree and start designing badges. Then I read what we would be putting the badges on.

The Problem

Our availability engine answers one question well: is this time free. It was never asked what the day looks like, and it turns out those are different questions.

Three things, in the order they surprised me.

The times we show sit on a fixed half-hour grid, and the grid starts at opening time. Not at the end of the last appointment. So a shop that opens at nine offers nine, half past nine, ten, and onward, all day, whatever is already booked. If a service runs forty five minutes, every booking made against that grid pushes the real end of the work off the grid the next one is offered on. The offsets nobody wanted are not a customer behaviour we need to nudge. They come out of the spacing we chose.

Nobody chose it, exactly. The spacing is fixed in the engine. It is not a setting, and no business can change it, which also means the research's whole idea of merchant control over strictness has nothing to attach to yet. There is no buffer setting either. What there is instead is five minutes, always, held clear after an existing appointment.

Five minutes is not nothing. It is also the same five minutes for a haircut and for a colour, and it only works on one side. A new appointment cannot start within five minutes of one finishing. It can end at the exact moment the next one begins, with nothing in between. I read that twice, because I expected the two sides to match, and there is no reason in the code for them to differ.

Then the third one, which is the reason for the title.

When a customer tells our booking assistant they do not mind who they see, we do not pick somebody for them. We record the appointment with no staff member attached, after asking the customer to confirm that is alright. The business sorts it out later.

That is a defensible product decision and I am not sure it was a decision. Here is what it does to availability. Our sense of who is free is organised around individual staff members, and an appointment that names nobody sits outside that. So it does not narrow what the next customer is shown, and the day can look more open than the shop can staff.

It does not reach every business the same way. Working out exactly who it touches belongs in my own notes rather than on this page.

I want to be careful here. I read this in the code rather than reproducing it against a live calendar, and that is a real difference. A second appointment for the same person still cannot be created, because overlapping work for one staff member is refused at the level below, where I would want it refused. What I am describing is the list of times we offer, not the last line of defence, and being offered a time that is quietly gone is its own kind of broken.

Assumption vs Reality

What I Thought Would Work

Slot shaping is a scoring and presentation problem. Take the list of free times we already produce, score each one by how much of a hole it would leave, badge the best few, and leave everything else visible and bookable. It is additive, it does not touch the engine, and merchant control is a toggle and a strictness setting on top.

What Actually Happened

Every word of that is still what I want to build. The problem is the first four words of it. There is no list of free times to take. There is a list of times that pass one narrow test, generated on spacing nobody picked, with a gap rule that works on one side, and with at least one category of booking that does not register at all. Score that list and you do not get a weak recommendation. You get a confident one. A badge is not a neutral display: it is us telling a customer that this time is the better one to take, with the business's name attached. If the calendar underneath can be emptier than the real day, the strongest thing we say is the thing most likely to be wrong. That is the part that changed my mind about sequencing rather than about direction. Recommend, do not hide, is correct. It just is not first. There is a second-order version of this I nearly missed. The research proposes proving the engine works before shipping it, by replaying historical bookings through a candidate version and comparing the schedules it would have produced. That is the right instinct, and the strongest version of it wants a record of what the calendar looked like at the moment each booking was made, which we do not keep. Build Note #018 wanted the same record from the cancellation side, so that is twice now. It is not the only way to measure this. Counting the holes a business ends the day with, before and after, would tell us something real, and so would asking a few owners whether the times we marked were the ones they would have chosen. Replay is the most rigorous option, not the only door.

The Fix

What changed is the design, not the code. Four things I now believe.

Accuracy before ranking, and accuracy is a smaller job than ranking. Every appointment has to hold time against whoever will actually do the work, including the ones booked without a preference. Whether that means choosing a staff member at booking, or holding the time provisionally across the ones who could do it, is a design question worth a week. It is not a research question, and nothing in the roadmap node makes sense before it.

Spacing and buffers belong to the business, not to us. The grid and the five minutes are our defaults wearing the costume of physics. Before anything ranks slots, a business needs to be able to say how their day is spaced and how much room they need between appointments, because the difference between a good gap and a wasted one is a fact about their work that we have no way to learn.

Recommend, never hide, and say why. I am taking the research's answer on the main question. Show the times that suit the day with a plain mark on them, leave every other valid time exactly where it is, and if the customer taps the mark, tell them the truth in one sentence: this time fits neatly with what is already booked. Customers with a flexible afternoon will help a business they like, if asked honestly. Customers without one keep their appointment, and the business keeps the booking, which is worth more than the tidier calendar it did not get.

Hiding stays off the table, and not only because of conversion. A time that is bookable and invisible is a lie about the shop's capacity that the shop did not tell. The owner cannot see what their customers were not shown. If we ever hide, it has to be something the business turns on knowing exactly what it costs, and that is a much later conversation than this node.

Lesson Unlocked

An availability engine and a picture of the day are not the same thing, and one of them is much easier to build. Ours answers is this time free, one time at a time, and it answers well enough that the product has run on it for as long as there has been a product. It was never asked what the day looks like. That question needs the parts nobody needs for a yes or no: the shape of the work, the space around it, and who the work belongs to. The failure mode is that the second question looks like a feature you add on top of the first. It is not. It is a different question that happens to use the same data, and you find that out when the answer is confidently wrong rather than missing. The general version. Before building something that gives advice, check whether the thing underneath was built to describe reality or only to permit actions. The permitting kind can be right about every single decision it was designed to make and still be the wrong foundation for a recommendation, because a recommendation is a claim about everything it did not consider.

Business Translation

For a salon owner, here is where this stands. Everwood does not shape your appointment times at all right now. Customers see every free half hour, in order, and pick whatever suits them. If that leaves you with an hour you cannot sell, nothing in the product is trying to prevent it, and there is no setting for you to adjust. Two things about how we work out those times that you should know, because they are yours to be annoyed about. The times are always half an hour apart, starting from when you open. If your services do not fall into neat half hours, that spacing is where your awkward offsets come from, and you cannot currently change it. We keep five minutes clear after an appointment and nothing before it, which is our number, not a question anybody asked you. And if a customer says they do not mind who they see, the appointment is saved without a name on it. That is on purpose so you can assign it yourself. What I had not thought through is that a booking with no name on it does not take anybody's time off the list, so the next customer can be offered a slot you have no room to cover. I would rather tell you that than ship a feature that recommends times on top of it. What I want to build for you is not a system that decides your day. It is a small mark on the times that fit neatly around what you already have, with every other time still there and still bookable, and a switch to turn the whole thing off on the week where nothing is normal. Before any of that, the times we show you have to be true, and your spacing has to be yours.

Builder Notes

A research pass on shaping appointment availability that turned into reading how our own times are generated. Nothing was built. There is no ranking, badging, gap minimisation, or utilisation balancing in the product.

Technical Note 1

Shipped today: an availability engine that returns free times in chronological order for a date, a service duration, and optionally a chosen staff member. It carries no score, no weight and no ordering beyond the clock.

Technical Note 2

The spacing between offered times is a fixed half hour, restarting at the beginning of each opening window rather than following the work already booked. It is fixed in the engine and there is no business setting for it.

Technical Note 3

The length of an offered slot is the service duration, so a service that is not a multiple of half an hour sits on a grid that does not match it. The offsets that produces are ours, not the customer's.

Technical Note 4

The only gap protection anywhere is five minutes held after an existing appointment. It is the same five minutes for every service, and it applies on one side only. A candidate time may end at the exact moment an existing appointment starts.

Technical Note 5

There is no merchant setting for padding, buffers, spacing, or gap policy. The research's recommended controls, a master switch and a strictness threshold, would be the first settings of their kind in this area rather than adjustments to existing ones.

Technical Note 6

Appointments that are still pending or awaiting a consultation hold time alongside confirmed ones, which is the behaviour I would want and worth recording because I had to check.

Technical Note 7

When a customer expresses no staff preference, the booking is recorded unassigned after the customer confirms that is acceptable, and it names no staff member. Because our sense of availability is organised per staff member, a booking like that does not narrow what the next customer is offered. How far it reaches depends on how a business is set up, and those specifics stay in my notes.

Technical Note 8

Read from the code rather than reproduced against a live calendar, and worth someone confirming deliberately before it is designed around. The database still refuses two overlapping appointments for one staff member, so this is about what we offer, not about what can be created.

Technical Note 9

Minimum notice exists, defaults to an hour, and is applied by the parts of the product that call the engine rather than inside it. So the engine's idea of what is available and the customer's idea already differ by one rule, and any ranking added inside the engine would score times that a later step may remove.

Technical Note 10

There are already separate slot-finding paths for parties and for mixed-service bookings. Any shaping logic has to be built somewhere all of these can use, or the recommendation will be right on one booking path and absent on the others.

Technical Note 11

The research's structural advice is the part I am keeping: absolute limits, like opening hours and someone's time off, are a different kind of rule from preferences, like closing a gap, and the first kind must never be overridden by the second. That is worth writing down before any scoring exists, because it is the rule that keeps a clever engine from booking somebody on their day off.

Technical Note 12

Reported by merchants and not verified: that owners close awkward gaps by hand, texting customers to move an appointment by a quarter of an hour, or blocking fake time on their own calendars to force the next booking to sit where they want it. Also reported: that they distrust scheduling automation that quietly blocks capacity through misread buffer rules, and want a way to override it. No figures survived on either side.

Technical Note 13

The market splits into two families, ranking preferred times or hiding valid ones. That split is the one genuinely useful thing the competitor section gave me. Every specific mechanic attributed to a named platform arrived without a source I could open, so none of it is in this note.

Technical Note 14

Cut from the research and kept in the ledger: the hourly and weekly loss arithmetic, the turnover rate, the hours-per-year admin figure, a competitor's adoption and voting numbers, another's per-minute slot valuations, the conversion rate range, the named revenue metrics, the named choice model, and the named solver engines. Not one carried a source.

Technical Note 15

Fourth time: the research came back with a finished public article attached, describing a smart slot engine at Everwood in the present tense.

Before / After

How I was framing it
  • The question is whether to rank slots or hide them
  • Slot shaping is scoring and presentation on top of the engine
  • Our availability list is the set of times that are free
  • Merchant control means a toggle over new behaviour
  • A no-preference booking is a booking like any other
How I frame it now
  • The question is whether the list we would rank describes the day
  • The engine answers whether a time is free, which is a narrower question
  • Our availability list is the set of times that pass one test
  • Merchant control means spacing and buffers that do not exist yet
  • A no-preference booking takes nobody's time off the list

What I'd Do Differently

I would have read how our times are generated before asking how they should be ordered.

The research is good on the question I asked and the question was one step too far along. It compares nine platforms on how aggressively they shape availability, and every one of those comparisons assumes the thing being shaped is an accurate calendar. Ours is not yet, and one afternoon in our own engine would have told me that before I commissioned a word.

The general version, and it is the same one as last time in a different costume. When research is about improving something you already run, the current behaviour of that thing is the first document, and I am the only one who can write it.

Next Experiment

The first step is not slot shaping. Take one test business with two staff members, book an appointment with no preference, and then look at what the next customer is offered. My expectation is that the day still looks open on the staff member who will end up doing that work. If that is what happens, the question in front of us is not ranking, it is what an unassigned booking should hold, and that is a design decision about how a business runs rather than an algorithm. Then spacing, as a setting. Let a business say how far apart their times should sit and how much room they need after an appointment. No ranking, no recommendations. Just their numbers instead of ours, which is a small change that would improve the product for every business whose services are not half an hour long, and which has to exist before anything can score a gap against what they consider a gap. Then, and only then, the mark on the good times. My guess is that the useful version is smaller than the research's: one clearly better time per part of the day, plainly labelled, everything else untouched. I would rather find out that a single honest suggestion moves nothing than build a scoring system first and be unable to tell which part of it failed. What I am not going to do is hide a valid time. Not in this version, and not without a business deciding it with their eyes open.

ResearchSaaS ArchitectureBooking WidgetAutomation

The information on this website is provided for general educational purposes only and may not apply to your specific setup or environment. It should not be considered professional advice. Always consult a qualified technician when appropriate.