One hop, whichever door you came through
A helper looked up the hall itself when nobody handed it one, costing a wait. The screen, the save, the crons and the webhooks all came through it.
The kitchen screen's settings are layered. The platform sets a default, the food hall can lock a value for every kitchen under it, and the kitchen keeps its own choices where nothing above has locked them. One helper walks that chain and returns the merged answer, and it is called from everywhere: the settings screen, the save that follows, the nightly jobs and the delivery webhooks that need to know how a kitchen wants its tickets handled.
To walk the chain the helper needs to know which hall the kitchen is in. When a caller already knew, it could hand the hall over. When a caller did not, the helper read the venue row to find out, then read the policies. Two waits. The policy screen's route then read the same venue row a third time, for the same column, because it wanted the hall id for its own purposes and did not know the helper had just fetched it.
Three readers of one row
The front door of the back office already reads that venue row before any route runs. It is how the server decides whether you are allowed to see the venue at all, and it hands what it read to the route. So the row had been read by the gate, read again by the helper, and read a third time by the route, and all three were asking for the same hall id. On a morning when the database was answering slowly that screen took two seconds, and worker time said three hops where one would do.
Making the helper one hop from every door
The fix had two halves. The route now takes what the front door already read and passes the hall id into the helper, so for the screen that is a single read of the policies. But the helper is also reached by callers that have not been through the front door, the crons and the webhooks, and those should not pay two hops either. So the helper no longer looks the hall up first. It finds the hall by a subquery inside the policies statement itself, with the handed-in value taking priority when there is one. One hop, whichever way you arrive.
The same morning the prep-areas screen had a cousin of the fault: the permission check, the list of areas and the menu were each awaited after the last, all keyed on the id in the address. They now run together, and the permission check still decides before anything is returned.
What we checked before shipping
A harness drives the real worker with a database that charges a fixed delay per call, so calls launched together overlap and calls in a line add up. It pins the policy route at two serial steps, where the stashed version measured four, and the prep-areas route at two, where a vendor's account used to pay four. It also checks the answers: a hall that has locked how many cooks a kitchen shows gets its value through, a platform default flows down where nothing overrides it, and a kitchen with no hall still answers with its own row. Beside the database the policy route went from thirty milliseconds to about ten. From a UK browser each removed hop is a hundred milliseconds, and on a slow morning several times that.