Airline Economics · Revenue management

Booking limits

How airlines keep seats for passengers who book late and pay more, starting from one flight with two fares, and how many seats they sell twice.

Cheap fares sell first and expensive ones last, so revenue management caps each fare class and keeps seats for later, higher-paying bookings. Three steps: two fares with Littlewood's rule, many fares with EMSR-a and EMSR-b on thousands of simulated flights, and overbooking for no-shows. The hands-on companion to Revenue Management 101, chapter 03.

The rule, one seat at a time

Each bar is one more seat you could keep for the high fare. Its height is the chance that high-fare demand gets that far, so that a high-fare passenger is there to buy it. Keeping the seat is worth the high fare times that chance; selling it now is worth the low fare for certain. The two are equal where the bars cross the dashed line at low fare ÷ high fare.

Fill the flight

Same customers, three choices

One departure, booked three ways. Low-fare customers book first until the seats on sale to them are gone. Then the high-fare customers arrive, and only the protected seats are left for them. Protect too few and some are turned away; protect too many and seats fly empty.

Too few, too many, just right

Average revenue per flight

One flight can go either way: on a quiet day protecting fewer seats would have earned more, on a busy day more. What Littlewood's level wins is the average, over every departure with this forecast. The curve shows that average for every possible protection level.

From two fares to many

EMSR-b, the industry workhorse

Real flights sell six to twenty booking classes, not two. The same comparison is made at every step down the fare ladder: how many seats to keep for all the classes above against the next class down. EMSR-b (Belobaba, 1992) merges the classes above into one, with their average fare and combined demand, and applies Littlewood's rule to it. These are the protection levels it sets on the example flight of the next tab: 150 seats, six classes from $620 down to $130.

Next: many fares → Change all six fares and forecasts, compare EMSR-a and EMSR-b, test them on 2,000 flights.

How it works

Background

Cheap fares sell first and expensive ones sell last, so a flight left to itself fills up with the cheapest passengers. Revenue management sets a cap on each fare class and keeps the rest for later, higher-paying bookings. The field started there: in 1972 Ken Littlewood, at BOAC, showed that you should keep protecting one more seat as long as the chance that high-fare demand reaches it is greater than the low fare divided by the high fare. The second step applies that rule down a ladder of six classes with EMSR-a and EMSR-b and tests the caps on thousands of simulated flights; the third decides how many extra bookings to accept for no-shows.

Two fares: Littlewood's rule

One flight leg with C seats and two fares, fH > fL. Low-fare customers book first and are plentiful. High-fare demand DH is uncertain: a normal draw with average μ and spread σ, rounded down to whole passengers (a negative draw counts as zero). Protecting y seats means the low fare is sold until C − y seats are gone (its booking limit), and the last y are kept for the high fare.

Revenue. With y seats protected, average revenue is R(y) = fL (C − y) + fH E[min(DH, y)], and for whole-number demand E[min(DH, y)] = Σk=1…y P(DH ≥ k).

Littlewood's rule. Protecting the y-th seat changes revenue by R(y) − R(y − 1) = fH P(DH ≥ y) − fL. That gain shrinks as y grows, so the best protection level y* is the largest y with P(DH ≥ y) ≥ fL / fH, capped at C. Because demand is a normal draw rounded down, P(DH ≥ y) = 1 − Φ((y − μ) / σ) exactly for whole y ≥ 1, which is what the bars show, and y* is the whole part of μ + σ · Φ−1(1 − fL / fH). With the default numbers, the ones in RM 101's worked example: 40 + 10 × 0.253 = 42.5, so protect 42 seats.

Fill the flight. "Too few" and "too many" protect one spread (σ, rounded, at least one seat) below and above y*. Each flight draws one high-fare demand from the forecast; all three cabins see the same customers. "New flight" draws another. The random generator is seeded, so the page always opens on the same flight. Which seat a passenger takes is only for the picture: airlines protect a number of seats, not particular seats.

From two fares to many. EMSR-b protection for classes 1 to j against class j+1 uses the composite fare f̄ = Σ fiμi / Σ μi and demand N(Σ μi, Σ σi2): yj = μ̄ + σ̄ · Φ−1(1 − fj+1 / f̄), rounded to the nearest seat as in the many-fares tab, whose default flight it uses. Rounding to the nearest seat rather than down can give one seat more than the two-fare rule above.

Many fares: seat allocation

Classes are ranked from the highest fare f1 to the lowest fn. Demand for class i is independent and normal, Di ~ N(μi, σi2). Everything rests on Littlewood's rule: keep one more seat for a higher fare fH as long as fH · P(DH ≥ y) ≥ fL, the lower fare you would turn away. The left-hand side is the expected marginal seat revenue (EMSR) of the y-th seat, and the charts plot it seat by seat.

EMSR-b (Belobaba, 1992) protects classes 1 to j together against class j+1 by merging them into one composite class, with fare f̄ = Σ fiμi / Σ μi and demand N(Σ μi, Σ σi2). The protection level is yj = μ̄ + σ̄ · Φ−1(1 − fj+1 / f̄). EMSR-a (Belobaba, 1987) applies Littlewood's rule to each higher class on its own against class j+1 and adds up the results. Protection levels are rounded to the nearest seat, kept between 0 and the capacity, and never allowed to fall as you go down the classes. The booking limit of class j+1 is the capacity minus yj; the top class can sell the whole cabin.

Monte Carlo: 2,000 departures, each with a fresh demand draw per class (rounded, and floored at zero). Bookings arrive strictly from the cheapest class to the most expensive, which is the textbook assumption behind EMSR and the case where control matters most. All policies see the same draws. The random generator is seeded, so the page opens on the same results every time; "Run 2,000 new departures" changes the seed.

Overbooking

With A bookings accepted and a show-up rate p, the number of passengers at the gate is binomial, S ~ Bin(A, p). The expected cost is cDB · E[(S − C)+] + csp · E[(C − S)+], where C is the capacity. One more booking is worth accepting while the chance that everyone else leaves a seat free, P(SA ≤ C − 1), is above the critical fractile cDB / (cDB + csp). The page also computes the expected cost for every level and checks that the minimum is where the rule says. With separate business and leisure rates, bookings are split by the business share and show-ups are the sum of two binomials; the page then takes the level with the lowest expected cost directly.

Sources

Limitations

This is a personal project and isn't affiliated with any airline.