Your busiest room can be your worst earner
Occupancy hides it. A small party filling a large private slot looks like a good night and a bad one at the same time, and most booking systems will never tell you which you are looking at.
One identity, three levers
Revenue per available slot is the number that reconciles everything else, and it is not a headline metric. It decomposes, and the decomposition is the useful part.
Did the room sell at all. How many heads were in it. What each head actually paid. Multiply those three and you have what the slot earned. When yield moves, you can see which of the three moved it, which is the difference between knowing something changed and knowing what to do.
A platform that cannot show group-size mix cannot explain why yield moved, and most of them cannot.
Counting slots you were never selling makes you look worse than you are
If a room is blocked for a private event, a maintenance window or a day you were closed, that slot was never available to sell. Counting it in the denominator understates your real fill and sends you chasing a problem that is not there.
Occupancy here is measured against saleable slots. Blocked and never-offered time is excluded, and the block itself is recorded, so you can also see how much capacity you took off the table and what it cost you.
Discounting that hides inside a healthy top line
Every booking is joined to the rate card version that was live at the moment it was made, and the intended per-head revenue is compared against what was realised. The gap is leakage, and it has a number.
Unfenced discounting collapses per-participant revenue while the top line still looks fine. It is the easiest way for a good month to be a bad month, and it is invisible unless something is measuring intent against outcome rather than just counting takings.
Rate cards are versioned and append-only, so a price change is a new fact rather than an edit to history. Last quarter still reconciles after this quarter's prices move.
The dashboard, the report and the export cannot disagree
Every metric has one definition, computed once and used identically on every screen and in every file. Inconsistent computation is treated as a defect rather than a quirk of whichever report you happened to open.
An organisation-level export sums to exactly the same total as the per-venue exports, and two overlapping date ranges agree with each other. Those are tested properties, not aspirations.
Reporting is rebuilt from an immutable record of what happened, which gives three things a capped system cannot. A report added next year covers the last five years rather than starting from the day it shipped. A bug is fixed by correcting the calculation and rebuilding rather than by editing rows. And every number traces back to one auditable source.
No two-year horizon. No three-month pull limit. No stitching exports together on a Sunday.
Revenue on its own is half the picture
Cost per booking, revenue per staff hour and margin distribution, read against your own roster rather than a number you type in once and forget.
Rostering stays where it already is. We connect to your existing system, read what is actually scheduled, and put it next to what was actually sold. You are not migrating your rostering to use this, and you are not being asked to.