Cargo revenue management
Why selling space in the hold is harder than selling seats, and what a bid price per kilo and per cubic metre does about it.
Passenger RM sells identical seats booked weeks ahead. Cargo RM sells space that runs out by weight or by volume, booked late and often tendered heavier, lighter or not at all. Below, one flight's hold is sold under first come, first served and bid-price control. Companion to Cargo 101, chapters 07 and 08; builds on RM 101, chapter 04.
Loading the scenario…
1. Five ways cargo is not passengers
The figures come from this scenario's demand: the requests one flight receives on average, and the flight you can step through in section 3.
One flight's booking requests, by weight and density
2. Two policies over 1,000 flights
The same 1,000 flights, each with its own booking requests, no-shows and tendered weights, go through first come, first served (accept while the shipment fits under the overbooking limits) and bid-price control (it must also fit, and its expected revenue must cover the bid-price value of the kilos and cubic metres it takes). Both keep the forwarders' allotments and overbook by the same amount, so the only difference is which shipments they accept.
Results per flight
Average of 1,000 flightsWho gets the space
Chargeable kg flown per flight, by shipper typeFlight by flight
Bid price minus first come, first served, net revenue3. Step through one flight
Requests arrive from 14 days before departure, most in the last few days. For each one: its kilos and cubic metres, what it pays, the bid-price value of the space it takes, and what each policy decides. The last step is departure day: who turns up, with how much, and what has to be offloaded.
Space booked so far
% of the aircraft's capacityBid prices
Bid-price policy, re-solved daily4. How much to overbook
Overbooking fills the space that no-shows and short tenders would leave empty, at the risk of offloading cargo when more turns up than fits. With two dimensions there are two levels to set, and the right ones depend on how unpredictable the show-up is. Each cell is the average net revenue of the bid-price policy at one pair of levels, over 1,000 flights (300 for the freighter), after the offload cost. Click a cell to use it above.
Net revenue per flight
Best net revenue at each weight overbooking level
Volume level set to its best, by show-up variabilityThe optimum against show-up variability
How it works
Background
Passenger RM sells identical seats, booked weeks ahead by people who mostly turn up. Cargo RM sells one space that can run out by weight or by volume, to shipments of every size and density, booked in the last few days by forwarders who often hold space in advance, and who then tender more or less than they booked, or nothing at all. The page sells one flight's hold to four kinds of shipper under two policies: first come, first served, and bid-price control, which values each kilo and each cubic metre with a small linear program and accepts a shipment only if it pays for the space it takes. Both overbook, and both pay for any cargo they have to offload. The network version of bid prices is on the network bid prices page.
The flight and its demand
One flight, either the belly of a long-haul passenger widebody (16,000 kg and 110 m³ available for cargo) or a large main-deck freighter (95,000 kg and 580 m³ usable). Both are assumptions in round numbers: a belly's cargo capacity depends on the passenger load, bags and fuel on the day, and a freighter's usable volume is well below its gross hold volume because pallets are contoured and never packed perfectly. For scale, Boeing lists a maximum structural payload of 107 tonnes for the 777 Freighter.
Booking requests come from four kinds of shipper, each with its own rate, timing, show-up rate and mix of densities (all in cargorm.json):
- Allotment: forwarders that hold 30% of the flight's weight and volume under contract, at US$2.00 per chargeable kg. They book into their block mostly in the last week, and 70% of their bookings show up. Unused allotment space is released to free sale 48 hours before departure; after that, their bookings are treated like anyone else's.
- Spot: general cargo booked ad hoc at about US$2.60 per kg, 85% show-up.
- Express and e-commerce: small, light parcels at US$3.60 per kg, booked very late, 95% show-up.
- Special cargo such as temperature-controlled pharma: US$5.50 per kg, booked earliest, 92% show-up.
For one flight, the number of requests from each shipper type is a Poisson draw whose mean is itself random (a gamma factor with a 30% coefficient of variation). Each request gets a weight from a lognormal distribution (capped at 3,000 kg and 12 m³ in the belly, 12,000 kg and 60 m³ on the freighter), a density from one of two or three profiles (dense, standard, light, each with ±20% lognormal noise), a rate with 15% lognormal noise around its type's rate, and a booking time: the share of the 14-day window elapsed is Beta(5, 2) for allotments, Beta(4, 2) for spot, Beta(7, 1) for express and Beta(2, 2) for special cargo. "Balanced" demand asks for about 1.75 times the flight's weight capacity in booked kilos; the other two demand settings shift the mix and scale every density by 0.8 or 1.35.
What a shipment pays
Air cargo is charged on the chargeable weight, the higher of the actual weight and the volume weight. IATA's general rule is to divide the volume in cm³ by 6,000, so one cubic metre counts as 166.67 kg: cw = max(w, 166.67 v), and revenue = rate × cw.
Bid prices from a two-resource linear program
At 14 days out and then about once a day, the bid-price policy solves the deterministic LP for the demand still to come. Each product j is a shipper type in one density profile, with expected remaining requests Dj, average weight wj, average volume vj and expected revenue rj:
maximise Σj rj xj subject to Σj wj xj ≤ Cw, Σj vj xj ≤ Cv, 0 ≤ xj ≤ Dj,
where Cw and Cv are the kilos and cubic metres still free under the overbooking limits, net of the allotment block until it is released. The bid prices πw (US$ per kg) and πv (US$ per m³) are the dual values of the two capacity constraints. Because there are only two of them, the page finds them exactly without a solver: the dual, minimise πwCw + πvCv + Σj Dj (rj − πwwj − πvvj)+ over π ≥ 0, is convex and piecewise linear in two variables, so its minimum lies at one of the points where two of the lines rj = πwwj + πvvj (or the axes) cross, and the page checks them all. The results match an LP solver (HiGHS) to rounding.
A request with booked weight w, volume v and revenue R is accepted if it fits and its expected revenue covers the value of its space: s t̄ R ≥ πww + πvv, where s is its shipper type's show-up rate and t̄ the average tendered share of booked weight. The same rule prices a dense shipment mainly by its kilos and a light one mainly by its cubic metres, so when the hold is short of volume, bulky low-rate cargo is turned away first. Requests within a forwarder's remaining allotment are always accepted: that is the contract.
Show-up, overbooking and offloads
Every accepted booking either shows up or not (with its type's show-up rate, scaled by the variability setting). If it shows, the tendered weight is the booked weight times a uniform factor (70–110% at medium variability, 85–105% at low, 55–115% at high), and the tendered volume is the booked volume times the same factor times a lognormal error with a 5% upward bias, because shippers tend to under-declare volume. Both policies accept up to the capacity times one plus the overbooking level, set separately for weight and volume. At departure, if the tendered cargo is over the aircraft's weight or volume, general cargo (allotment and spot) is offloaded before express and special cargo, starting with the least revenue per share of the aircraft it uses, until the rest fits; anything removed that turns out not to be needed is put back. An offloaded shipment earns nothing on this flight and costs the offload cost per chargeable kg: US$4.00 by default, more than any rate, because the cargo still has to move (handling, storage, trucking or space on a later flight) and the customer was promised this one. Net revenue = revenue flown − offload cost.
The overbooking grid in section 4 is precomputed by scripts/cargorm/precompute.js with the same code as this page, for every scenario, on 1,000 flights per cell for the belly and 300 for the freighter, in 5-point steps from 0 to 60%, and stored in cargorm-overbooking.json. It stores revenue and offloaded kilos separately, so a new offload cost only needs a subtraction. Sections 1 to 3 run live in your browser, and the generator is seeded, so the page opens on the same flights every time.
Sources
- Kasilingam, R. G. (1997), "Air cargo revenue management: characteristics and complexities", European Journal of Operational Research 96(1), 36–44. The classic list of how cargo differs from passenger RM: two-dimensional, variable capacity, allotments, uncertain show-up.
- Amaruchkul, K., Cooper, W. L. and Gupta, D. (2007), "Single-leg air-cargo revenue management", Transportation Science 41(4), 457–469. Booking control for one flight with random weight and volume, offloading costs and heuristics that value weight and volume separately.
- Luo, S., Çakanyıldırım, M. and Kasilingam, R. G. (2009), "Two-dimensional cargo overbooking models", European Journal of Operational Research 197(3), 862–883. Overbooking limits for weight and volume together, trading spoilage against offloading.
- Levin, Y., Nediak, M. and Topaloglu, H. (2012), "Cargo capacity management with allotments and spot market demand", Operations Research 60(2), 351–365.
- IATA, "Air cargo tariffs and rules: what you need to know": the volume divisor of 6,000 cm³ per kg and the chargeable weight (checked September 2026).
- Boeing, Freighters: 777 Freighter maximum structural payload (checked September 2026).
- Charts drawn with D3 7.9.0.
Limitations
- The LP uses expected demand only, so its bid prices ignore uncertainty and move in steps; they can be zero on a dimension the forecast doesn't fill. Amaruchkul, Cooper and Gupta build stronger value-function approximations. Real systems also forecast show-up by customer and booking history, not by shipper type alone.
- Space is treated as two numbers. In a real hold, cargo goes on pallets and in containers of fixed shapes, contour limits and floor loading matter, and dangerous goods and live animals have their own positions, so a flight can be "full" before either number reaches 100%. A belly's capacity is also uncertain until passengers and bags are known, which this page ignores.
- Rates are given, not optimised, and there is no negotiation: in practice spot rates are quoted per shipment, and an RM system uses the bid prices as a floor for the quote (see RM 101, chapter 07 on dynamic pricing).
- One flight at a time. On a network, a shipment's bid price is the sum over the flights it uses, and trucking and alternative routings change the cost of offloading (see RM 101, chapter 06 and the network bid prices page). No-show fees, booking cancellations and rebooking before departure are not modelled.
- Allotments are a fixed 30% block with a fixed release time. Real allotment contracts vary (hard and soft blocks, use-it-or-lose-it clauses, different release times), and choosing how much to sell as allotment is a decision of its own: see the allotments vs spot page and Levin, Nediak and Topaloglu (2012).
This is a personal project and isn't affiliated with any airline.