A standard king room at a 4-star business hotel a short walk from Plaça d'Espanya in Barcelona cost £142 on a normal Sunday night in January. Same room, same hotel, same guest profile — on the Tuesday of Mobile World Congress, £610. Any company whose hotel policy says "Barcelona: €180/night" has a traveller staring at an out-of-policy booking for a completely legitimate business trip.
We didn't set out to fix this. Helix started life as a luxury travel tool — we were focused on beautiful itineraries, not enforcing corporate policy. Then early users kept telling us something we weren't expecting: they took at least twice as many trips for work as for leisure, and the work ones were the painful ones. Our first blog post covered the thing we dug into first: flight policy, and how a concept called Lowest Logical Fare quietly solves the fixed-cap problem. This piece is about the second thing we found — hotels — which turned out to be the harder and more interesting problem to solve.
Hotels are not flights
The reflex, when you've just built something for flight policy, is to assume the hotel version is the same problem in a different costume. It isn't. Three things make hotels genuinely harder:
Dispersion is much wider. For a given route on a given date, most flights cluster within 30–40% of each other. Hotels don't. A single neighbourhood will have rooms from £95 to £750 on the same night, in properties that all reasonably claim to be "4-star business hotels". The spread isn't an error — it's the actual market. Which means any benchmark you set has to be intelligent about what it's comparing.
Micro-geography matters enormously. A "London" cap is almost meaningless because Canary Wharf, Westminster, Stratford and Heathrow are four different hotel markets. A traveller meeting a client in La Défense doesn't have the option of staying in the Marais because that's where the cheaper rooms are. For flights the destination is the destination; for hotels, the destination is a two-kilometre radius around a specific address, and prices can double over a three-block walk.
Events distort the market more violently. An MWC week in Barcelona, an F1 weekend in Singapore, a Dreamforce in San Francisco — these don't nudge rates, they multiply them. A hotel that runs £140 for 51 weeks of the year will run £600+ for the other one, and every policy grid in corporate travel assumes the £140 is the baseline. Flight prices do this too, but less brutally.
So the hotel problem isn't "fixed caps go stale" — it's "fixed caps were never the right tool for a market that's this dispersed, this geographically sensitive, and this event-driven". That's a different starting point, and it leads somewhere different.
How hotel pricing actually moves
To understand why per-diems are quietly failing, it helps to see how hotels arrive at the rate on the screen.
Most major chains now run revenue management systems that recalculate rates many times per day. The inputs include current booking pace versus forecast, competitor rates scraped from rate-shopping tools, anticipated group bookings, weather, citywide event calendars, and — yes, really — inbound flight arrivals data. The output is what the hotel's best guess of the next room's value is at that exact moment. Independents and smaller chains use lighter versions of the same thing through channel managers. Even individual Airbnb hosts get nudged by algorithmic pricing tools.
The practical effect is that a 4-star business hotel in Paris might list at €165 on a quiet Sunday in February and €380 on a Wednesday during a mid-sized trade show six weeks later. Not because anything is broken — because that's what sophisticated revenue management looks like when it runs against a spreadsheet cap that hasn't been touched since 2023.
Why per-diem grids can't keep up
Talking to travel managers over the past year, the failure patterns cluster into four specific things that are distinct to hotels:
The neighbourhood trap is the one nobody costs into their policy. A £180 London cap is fine for a traveller who can choose where they stay. It's unworkable for a traveller who has to be within walking distance of a specific meeting venue and discovers the only in-policy options are forty minutes and two train changes away. The traveller either overpays and explains it to finance later, or stays somewhere bad and privately decides the policy is stupid. Both outcomes are quiet compliance failures.
The category cliff is the one that sounds abstract but kills on contact. Policies written as "4-star — £180" assume 4-star means something consistent across cities. It doesn't. A "4-star" in suburban Lisbon and a "4-star" in central Zurich are entirely different products at entirely different price points, and the traveller who books the Zurich one at £290 isn't being extravagant, they're being normal. The grid has no way to know the difference.
The event spike is the most dramatic and the easiest to see coming. Most cities have three to eight weeks a year where hotel prices run 3–5x normal. These are visible on any conference calendar. And yet nearly every per-diem grid assumes the other 44 weeks of the year are the only thing that matters. The result is that the one week a traveller actually needs policy coverage — the week everyone else is also trying to book a hotel — is the week the policy becomes fictional.
The maintenance collapse is the failure mode that gets travel managers promoted out of travel management. Fixing the first three problems by adding more granularity (per-neighbourhood caps, seasonal adjustments, event carve-outs) turns the per-diem grid into a full-time job nobody signed up for. Within a year, most grids quietly stop getting updated, and the programme drifts back into "use judgement" — which isn't a policy, it's a permission structure built on goodwill.
Most travel teams we've spoken to have tried to fix this with more spreadsheet. It works for about a quarter. Then maintenance collapses and the cycle starts again.
The fix is a different kind of benchmark
Instead of writing a fixed nightly figure for each destination, dynamic rate caps compute a benchmark per booking from real market data at the moment the traveller searches.
The most robust version uses median market rate (MMR). The system pulls a wide sample of hotels comparable to the one the traveller is searching for — same destination area, same dates, similar category, similar amenity profile — and takes the median nightly rate across the sample. Median rather than mean because hotel price distributions are long-tailed: one £900 boutique in the sample would drag a mean up by 30%, but the median doesn't care. Your policy then sits as a percentage above the median, which means the cap might be €210/night in central Madrid one week, €175 the next, and €140 in regional France on the same policy line — all without anyone adjusting a single setting.
Same policy. Different answer everywhere, every time. The market does the work that finance used to do.
Our first article on LLF covered how this logic works for flights and why graduated enforcement (silent allow → warn → require approval → block) beats any single threshold. Everything there applies to hotels too, and there's no need to repeat the case — if you want the short version, read that piece first and come back. What's interesting about hotels specifically is the stuff the flight version doesn't have to deal with, which is where we spent most of the build time.
What we found when we built this
A few things surprised us when we actually put dynamic hotel caps into live bookings. These are the details that separate a dynamic cap from an opaque one:
Sample size matters more than you'd expect. A median computed from four hotels is just noise. We settled on 20+ comparable properties as the floor for a trustworthy number. In small markets the temptation is to filter aggressively (only 4-star, only a 1km radius, only specific chains) until the sample is too thin — so we built a graceful fallback that loosens the filter step by step until the sample is big enough, and reports the broader basis back to the approver so it's never a black box. Better an honest "median of 24 3-and-4-star hotels within 3km" than a precise-looking number based on four.
Comparability is the quiet 80% of the work. "Median across all hotels in Paris" would be meaningless — the dispersion is enormous. The useful benchmark filters to like-for-like: same star tier, comparable amenity profile (business vs leisure), similar location class, similar room type. The traveller sees the comparison set in plain language — "median across 28 four-star business hotels within 2km of the venue" — which turns a number into an argument, and arguments are what survive contact with travellers.
Benchmarks have to freeze at booking start. Hotel prices move during the booking flow. If a traveller starts choosing at 10:00 with one cap and finishes at 10:18 with a different cap because the median shifted, the entire experience disintegrates. We freeze the benchmark to the trip the moment the booking flow opens, and the frozen number is what the approver sees later. This single design choice did more for traveller trust than any UI polish we tried.
Events need their own logic. A plain MMR benchmark handles event pricing naturally — every hotel in the sample is up, so the median is up, and the cap moves with reality. But there's a better move: flag known event weeks in advance and nudge travellers to book earlier, when the market is still soft. Most of the money on event weeks is made in the first 48 hours after the dates are announced, and a good policy engine knows it before the traveller does.
Approvers must see exactly what the traveller saw. The single biggest source of approval friction in any travel programme is "the price was different when I picked it". When the approver sees the frozen benchmark, the comparison set, the selection, the gap and the justification on one screen — that conversation simply stops happening. It's not glamorous. It's the detail that makes the rest work.
Get these right and dynamic caps run themselves. Get them wrong and you've replaced a stale spreadsheet with an opaque algorithm, which is a worse trade.
How to transition without breaking anything
Nobody should flip overnight from fixed per diems to dynamic caps. What we've seen work is a three-phase rollout over 60–90 days:
Shadow mode for the first 30 days. Travellers don't see anything new. The system computes the median and the gap for every booking in the background and logs both. At the end of the month, finance has a clean comparison of what each booking would have cost under dynamic caps versus fixed caps, and where the interesting differences cluster. This phase is mostly about building confidence internally.
Warn-only for the next 30 days. Travellers now see the benchmark and a warning if they go over, but nothing is blocked or held for approval. This builds familiarity and surfaces edge cases (unusual events, fallback samples, comparison filters) without operational risk.
Full enforcement from day 60 onwards, with graduated bands layered on top. At this point the per-diem grid can be retired as the primary control mechanism. Most programmes keep one absolute ceiling — "no single night over £600, ever" — as a backstop for extreme outliers, which is sensible.
The biggest blocker in any transition we've observed isn't technical. It's political — someone owns the per-diem spreadsheet and isn't sure what their role becomes when it goes away. That conversation is more important than any of the engineering.
FAQ
What is a dynamic hotel rate cap? A hotel cap computed per booking from real market data, rather than set as a fixed number in advance. The system queries a sample of comparable hotels for the destination and dates, calculates a statistical benchmark (most commonly the median), and applies your policy as a percentage over that benchmark. The cap moves with the live market.
Why use the median rather than the mean? Hotel price distributions are long-tailed, and the median is robust to outliers. A single £900 luxury property in the sample would pull a mean up by 30%. The median doesn't move. This matters more for hotels than for flights because hotel category dispersion is much wider.
Does this work in cities with limited inventory? Yes, with honest sample handling. If a strict filter returns too few hotels to be meaningful, the engine should broaden the sample (loosen the radius, drop a star tier) and surface the broader basis to the approver. The correct answer is "we computed this from a wider sample because the strict filter was too narrow" — provided it's visible, that's fine.
Do I still need a fixed cap as a backstop? Most programmes keep one absolute ceiling as protection against extreme outliers — the hotel equivalent of a circuit breaker. Dynamic caps handle the 99% of bookings that fall inside reasonable market behaviour. The circuit breaker handles the 1% that no benchmark can sensibly bound.
How does this handle major events like CES, Cannes or F1 weekends? The benchmark naturally rises with the market because every hotel in the sample is priced for the event. Travellers see a higher cap and a higher selection, both grounded in reality. A well-built policy engine can layer an advance-booking nudge on top for known event weeks, pushing travellers to book while the market is still soft.
How is this different from flight policy with LLF? LLF (Lowest Logical Fare) works for flights because flight prices on a given route cluster within a reasonably narrow band. Hotel prices don't — a single neighbourhood holds rooms at £95 and £750 in the same category. Median market rate is the hotel equivalent of LLF, tuned for the specific realities of how hotel inventory is priced and distributed. Both are instances of the same principle: stop writing fixed numbers into spreadsheets and start computing benchmarks from live market data.