← All playbooks·Inventory pricing

Playbooks · Inventory pricing

Track CPM compression across the market

This job produces a CPM compression percentage and a supply-linked compression coefficient for one format and period. It feeds the decision on whether to lock the current rate now or hold, based on how close the realized CPM sits to the discount grid floor.

What you need first

  • Realized (cleared) CPM by month for the target format, trailing 6-12 months, from internal buy logs or DSP reporting
  • Supply volume (available impressions) for the same format and period, from SSP or ad server supply reports
  • Current rate card list price and the discount grid's maximum negotiated discount, from sales contract terms
  • Audience or reach data for the same period, from panel measurement (Gemius, Nielsen, or equivalent)

The procedure

  1. Pull realized CPM for the target format from buy logs, not list price from the rate card, for the trailing 6 months to produce a monthly CPM series
  2. Pull supply volume for the same format and period from SSP or ad server reports to produce a monthly impression series
  3. Compute compression as (start CPM minus end CPM) divided by start CPM to produce a compression percentage
  4. Compute supply growth as (end supply minus start supply) divided by start supply for the same window to produce a supply growth percentage
  5. Divide the compression percentage by the supply growth percentage to produce a compression coefficient showing how much of the price move supply explains
  6. Check reach data for the period to confirm audience held steady, producing confirmation the move is supply-driven rather than demand-driven
  7. Compare current realized CPM to the discount grid floor (list price times one minus the max negotiated discount) to produce the cushion remaining in euros
  8. Flag whether the compression trend and remaining cushion justify locking the rate before the next card refresh, producing the buy decision

Worked through with numbers

NL online video pre-roll, H1 2026. Realized CPM: Jan €8.20, Jun €7.35. Supply: Jan 40M impressions, Jun 52M. Compression = (8.20-7.35)/8.20 = 0.85/8.20 = 10.4%. Supply growth = (52-40)/40 = 12/40 = 30%. Coefficient = 10.4/30 = 0.35, so roughly a third of the price move tracks supply, the rest is other factors. Reach data flat within 2% over the period, so demand isn't the driver. List price €8.50, max grid discount 15%, floor = 8.50 x 0.85 = €7.225. Cushion = 7.35 - 7.225 = €0.125, about 1.7% above floor. Read: compression is real and mostly supply-driven, but the cushion to floor is thin, so lock the rate this cycle rather than waiting for the next card.

Where it goes wrong

  • Using list price instead of realized cleared CPM overstates compression; pull the traded price from buy logs
  • Comparing sequential months absorbs seasonal swings into the compression number; check the trend holds for at least 2-3 consecutive periods or compare against the same period last year
  • Blending formats or placements when averaging CPM masks the real per-format compression; keep the series segmented by format
  • Flagging a single month's dip as compression; require the coefficient to hold across multiple periods before it drives a rate decision

How to know it is right

Recompute the compression percentage and coefficient independently from the raw CPM and supply series and confirm they match, and confirm the current CPM still sits above the discount grid floor before sending the number on.

Terms used