← Back
Home › Systems › Communication and media

tv-ad-sales

Sells a broadcaster's limited commercial slots by turning advertiser requests into orders of spots at negotiated rates, tracking which slots remain available in each break.

WideOrbit, Operative AOS, FreeWheel, Imagine Communications

Open the tv-ad-sales pagetv-ad-sales Durable workflow executiondistributed: Ordinary code made crash-proof by logging every side-effect result and replaying the code from that log; activities run at least once, workflow logic must be deterministic.›Budget pacingfinance: Spreading an advertiser budget over the day via throttling or bid multipliers with a feedback controllerDouble-entry ledgerfinance: Append-only journal of transactions whose postings sum to zero per currency; balances are derived, so money can only move, never appear or vanish.›Inventory reservationfinance: Reserving stock with TTL holds, release on timeout and no overselling under contentionMoney representationfinance: Store money as integer minor units with an explicit currency exponent, compute in wider integers, and round once with a named rounding mode.›Reconciliationfinance: Match internal ledger records against bank and processor statements by reference, then amount and date window; every unmatched or mismatched item becomes an exception.›Revenue recognition schedulesfinance: Deferred revenue schedules that recognize income over service periods (ASC 606 / IFRS 15)Tariff ratingfinance: Rate usage events against price plans: tiers, time bands, bundles and rounding rulesConstraint propagation(constraint programming)optimization: Variables with finite domains, propagators that prune impossible values to a fixpoint, and backtracking search with trail undo between decisions.›Simplex methodoptimization: Solves linear programs by walking along the edges of the feasible polytope from vertex to vertex, one basis swap (pivot) at a time; the workhorse behind MIP solvers.›Deduplicated reach estimationstatistics: Model deduplicated reach and frequency across channels from panel data (beta-binomial / Dirichlet reach curves, overlap calibration)Time-series forecasting(baselines, model families, ba…statistics: The end-to-end recipe: fix horizon and uncertainty, beat naive baselines, choose a model family, and validate with rolling-origin backtests and scale-free metrics.›Rollup aggregationstorage: Fold raw events into one mergeable partial aggregate per time bucket and dimension key, then merge fine buckets into coarser ones, so long ranges read few rows and stay exact.›XML Streaming Parserstorage: Tokenize XML into start, text and end events in constant memory, so a few fields can be extracted from huge, broken or hostile documents.›Calendar date arithmeticsystems: Civil dates, time zones (tzdb), DST gaps, month-end anchoring and duration mathHierarchical state machinesystems: Nest states so a substate inherits its parent's reactions and only overrides what differs, with ordered entry and exit actions along the path.›Durable job queuedistributed: Persisted tasks that workers lease for a visibility timeout, ack on success and retry with backoff; at-least-once execution that survives worker and queue crashes.›Record replaydistributed: Record every nondeterministic input (time, randomness, I/O, model and tool outputs, per-tick player input) and re-execute deterministically for debugging, replays and state rebuildEvent sourcingfinance: Persist state changes as an append-only stream of immutable events per entity; current state is a fold over them, guarded by expected-version appends.›PID controllerrobotics: Drive a measured value to a setpoint with three terms on the error: proportional, integral, derivative. The default feedback loop for motors, heaters, drones and gimbals.›Sliding-window counterssystems: Count events in the last W seconds with a ring of sub-bucket counters; the two-bucket weighted estimate gives rate limits in 16 bytes per key.›Hierarchical timing wheelsystems: Timers bucketed by expiry into wheels of slots, coarser wheels for far deadlines: O(1) insert and cancel for millions of timeouts.›Conditional writesdistributed: Put-if-absent / if-match compare-and-swap on objects or keys as a commit primitiveIdempotency keysfinance: Client-chosen unique key per logical operation, stored with a request fingerprint and the final response, so retries replay the first result instead of acting twice.›Hash joinstorage: Build a hash table on the smaller input's join key and probe it with every row of the larger one; the linear-time workhorse for equi-joins.›Largest remainder roundingfinance: Splitting an amount into parts that sum exactly (largest remainder / Hamilton) for allocations, splits and prorationsInterval treedata-structures: Index of ranges that answers "which intervals overlap this point or range?" in O(log n + k); static sorted-array form is the compact, cache-friendly choice.›Interval arithmeticnumerics: Rigorous bounds with outward rounding; root isolation and robust geometric tests+ 12 moreDead-letter queuedistributed: A side queue for messages that keep failing: after N delivery attempts or a permanent error, park them with the reason so the main queue keeps moving.›Write-ahead logstorage: Append each change to a checksummed sequential log and fsync it before touching data pages; the basis of crash durability in nearly every database.›Optimistic concurrency controlstorage: Run transactions without locks, record what they read, and validate at commit that nothing changed; fastest when conflicts are rare.›Leasesdistributed: A lock that expires on its own: bounded-time ownership that survives crashes and partitions, given bounded clock drift and fencing tokens on writes.›Exponential backoff with jittersystems: Retry after delays that grow geometrically and are randomized, so failed clients spread out instead of hammering a recovering service in synchronized waves.›Slab allocatorsystems: Pre-carve pages into equal-size slots per size class with an in-place free list: O(1) alloc and free, no external fragmentation, cache-warm reuse.›Cryptographic hashes (SHA-2,BLAKE3)security: Collision-resistant fingerprints of data; SHA-256 for interoperability, BLAKE3 for speed, HMAC/HKDF for keyed uses.›+ 5 moreCRC32C checksumshardware-os: The Castagnoli CRC-32 with dedicated instructions on x86 (SSE4.2) and ARMv8. It is the standard fast integrity check for storage blocks, logs and network frames.›fsync, O_DSYNC and O_DIRECThardware-os: What fsync, fdatasync, O_DSYNC, O_DIRECT and F_FULLFSYNC really guarantee on Linux and macOS, and the exact call sequences for crash-safe files.›Fencing tokensdistributed: A number that grows with every lock grant and is checked by the protected resource, so a paused ex-holder's late write is rejected.›PRNGs (PCG, xoshiro)numerics: Small, fast, statistically strong non-cryptographic generators: PCG32 and xoshiro256**, with seeding, parallel streams and unbiased ranges.›+ 4 moreSIMD programminghardware-os: Process 4-16 lanes per instruction with AVX2, AVX-512 or NEON via Rust std::arch, with runtime dispatch and a portable fallback.›

How it is built

Architecture overview

A broadcaster's sales and traffic system sells a finite, perishable inventory: the commercial slots in every break of every programme on every day. The sell side turns advertiser requests into orders (packages of spots at negotiated rates, often with a guaranteed audience); the traffic side decides which commercial runs in which break position, builds the playout log, receives the as-run log back, reconciles it against what was sold, and drives billing and makegoods for anything that did not air or under-delivered. The one idea that makes it work is the separation of three clocks: slots are sold months ahead against a forecast audience, scheduled days ahead against rules (competitive separation, rotation, position), and measured days after airing against actual ratings; the system's job is to keep the three consistent and to pay the difference. Linear TV ad sales sits next to addressable and programmatic sales, where the same break is sold impression by impression through an auction.

Parts:

 agency / advertiser ─► proposal ─► order ─► reservation on avails ─┐
        ▲                  ▲ rate card, forecast                    ▼
   invoices ◄─ billing ◄─ reconciliation ◄── as-run log ◄── automation / playout
        ▲                  │                                        ▲
        │            ratings (measured) ─► delivery vs guarantee     │ schedule log (BXF / file)
        │                  │                                        │
        └──── makegoods ◄──┘      scheduler ─► break positions ──────┘
                                  addressable / programmatic: ad decision per impression

How the parts fit together

Inventory and avails

An avail is an unsold unit in a break: programme, date, time, break number, remaining seconds, and a position class. Sales asks "what is available on these programmes next month for this target?"; the answer must be right at order time, even with many sellers working. Two blocks matter. A reservation with a hold and expiry is inventory-reservation (no page yet), whose job is to avoid overselling under contention: holds expire by timer (Hierarchical timing wheel at scale) and a commit is a conditional write (Optimistic concurrency control). Retries from a flaky client must not double-book, so every order mutation carries an Idempotency key. Overlapping-time queries ("every break that overlaps this daypart on these dates") fit an Interval tree or a plain index on date and daypart. Dates are harder than they look: the broadcast day runs past midnight, feeds run in several time zones, and daylight saving shifts a 02:30 break; that is calendar-date-arithmetic (no page yet).

Pricing

A rate card gives a price per unit (typically per 30-second equivalent) by daypart and programme class; negotiated rates, discounts and package prices sit on top. Rating usage events against price plans is the same problem as telecom tariffs: tariff-rating (no page yet). The financial rules are the ordinary ones: amounts as integer minor units (Money representation), a package price split over its spots so that the parts sum to the whole (largest-remainder-rounding, no page yet), one rounding step at the end.

Audience forecast

Sellers promise audience before the programme airs, so they forecast ratings per programme and daypart from past ratings. The recipe is the standard one in Time series forecasting: a naive seasonal baseline first, then Exponential smoothing or STL decomposition for level, trend and weekly and seasonal shape, with arima (no page yet) as the classical alternative; backtest by rolling-origin cross-validation. New shows and specials have no history; they inherit from comparable programmes. A spot schedule's deduplicated reach (how many different people see it at least once, and how often) is estimated from panel data; practitioners have long used a beta-binomial model for this (the Metheringham variant; see the ESOMAR paper on TV reach and frequency), which is the block deduplicated-reach-estimation (no page yet). The forecast sets the guarantee, and a bias towards optimism creates makegood debt.

Order management

An order lives for months: proposal, revision, approval, credit check, flight dates, cancellations, rotation instructions. Model it as an event stream per order (Event sourcing) so the history of every change is the audit trail and billing can be replayed. Steps that wait for people or for timers (approval, a hold expiring, a revision deadline) are Durable workflow execution on top of a Durable job queue with retries; a failed step is retried idempotently or parked, never lost. The trade-off versus a simple status column is that the event model is more work but answers "what did we sell, and what did we promise, on that date?", which is exactly what a dispute over a makegood asks.

Scheduling

Two optimisation problems share one name.

Selling optimisation chooses which orders to accept and where to place them so that revenue is maximised given a limited inventory and demand forecast. NBC's published system estimated demand for airtime by show and week, produced sales plans and scheduled commercials, and reported more than $200 million of added revenue between 1996 and 2000 (Bollapragada et al., Interfaces 2002). The core is a linear program over inventory with integrality where units cannot be split (Mixed-integer programming).

Spot placement puts each commercial into a break position under rules: competing products of different clients must not share a break, advertisers prefer the first and last positions in a break because ratings tend to be higher there, and the network promises an equitable rotation over positions. Bollapragada and Garbiras formulate this as an integer program with near-optimal heuristics, implemented at NBC. A related problem spaces repeated airings of the same commercial as evenly as possible (Bollapragada, Bussieck, Mallik, 2004). These are constraint problems: prune with Constraint propagation, solve with MIP for moderate sizes, and use Large neighborhood search to repair a schedule when a late change arrives. The scheduler's contract is a log: for each break, an ordered list of spot ids, lengths and positions, plus a reason for each placement so that a person can see why it moved.

The graph lacks edges to the MIP and local-search pages for this system; they are linked here because the problem needs them (see gaps).

Log exchange and as-run

The log goes to the automation system that plays the commercials. SMPTE's Broadcast Exchange Format (BXF, ST 2021 family) is the standard for exchanging schedule, as-run and content metadata between traffic and automation; it replaces vendor-specific interfaces, is XML-based, and was designed to allow real-time changes, status updates and reporting (SMPTE RP 2021-1; trade coverage). Before BXF the traffic system produced a print-style log file and automation returned an as-run file, and the gap between sending the log and receiving a reconciled as-run was reported as 36 hours to more than five days around weekends and holidays. Parsing large XML exchange messages in constant memory is the job of an XML streaming parser; the exchange protocol itself is BXF. Spots that did not run, ran short, ran in the wrong position or ran at the wrong time are found by Reconciliation: match scheduled to as-run by id, then by time window, and put every unmatched item into an exception queue.

In the play-out chain, a downstream signal marks the break. SCTE 35 (Digital Program Insertion Cueing Message) is the cue message carried in the transport stream: a splice_info_section with table_id 0xFC, whose splice_insert command signals one splice-out or splice-in at a PTS time (the out_of_network_indicator flag distinguishes the two), and whose time_signal command carries timing for descriptors that give it meaning (SCTE 35 summaries; the scte35-splice crate documents the 2023r1 edition). Cues start the break on air, trigger local ad insertion and tell a dynamic ad-insertion system where a replaceable break begins. A state machine in the automation system (Hierarchical state machine) moves each break through armed, in-break and returned.

Delivery, pacing and makegoods

A guarantee is stated as audience delivered for a target over a period; if the network under-delivers, the advertiser is credited with audience deficiency units (ADUs, also called makegoods): airtime owed elsewhere on the network's linear or digital properties. Over-delivery usually earns the network nothing extra (Digiday upfront primer). Commercial ratings are defined by the buyers and sellers: Nielsen's C3 is the average-commercial-minute rating including playback for up to three days, and C7 uses seven days (Nielsen; secondary sources). The system therefore needs three jobs. Measure: roll up rating records to spot, order and campaign level, using robust handling of outliers (Robust statistics). Compare: delivered against guaranteed per order and per week. Correct: if an order is behind, give it better placement on future spots; that is a feedback controller on delivery (PID control in spirit, with Sliding-window counters for pacing windows), and the budget-pacing block (no page yet) names the same pattern from online advertising. A makegood is another booking against future inventory, so it re-enters the avails, rate and scheduling chain; keep it as an explicit order type, not an edit on the original.

Billing and revenue

Invoices come from reconciled as-run, not from the sold schedule, as the traffic-to-billing hand-off described above makes explicit. Postings go into a Double-entry ledger (receivable, revenue, deferred revenue), and revenue-recognition-schedules (no page yet) spread revenue over the service period. Reconciliation against the ledger finds spots billed but not aired and the reverse.

Addressable and programmatic

Addressable TV replaces a spot in the linear feed with one chosen for a household or a segment. DVB Targeted Advertising (ETSI TS 103 752) standardises the signalling that lets a receiver find ad placement opportunities in a DVB transport stream and substitute a broadband-delivered advert chosen by a decisioning service (DVB; ETSI). In a connected-TV stream, the break becomes an ad pod in an OpenRTB request: OpenRTB 2.6 introduced ad pods for CTV, with fields such as podid, podseq, slotinpod, maxseq and poddur describing the pod, its position and the dynamic duration (IAB Tech Lab, OpenRTB 2.6). The sell side then runs two inventory models side by side: the guaranteed linear order, reserved in advance, and impressions offered to an auction at request time. They must share one view of the break, otherwise the same seconds are sold twice.

Data and control flow

An order from proposal to invoice

  1. Sales checks avails for the target programmes; the system places holds on inventory with an expiry.
  2. A forecast per programme sets the guaranteed rating; price comes from the rate card and package rules.
  3. On approval the order commits; holds become reservations (conditional write, idempotent).
  4. The scheduler assigns spots to break positions under separation, rotation and position rules and publishes the log.
  5. Automation plays the log; cues start each break; as-run records come back.
  6. Reconciliation matches log and as-run; exceptions create makegood bookings or credits.
  7. After the ratings window (for example C3's three days of playback) the measured audience is attached; delivery is compared with the guarantee.
  8. Billing posts invoice lines from the reconciled as-run; ADUs are scheduled as new inventory.

A last-minute change

  1. A programme runs long or is pre-empted; the break moves.
  2. The scheduler repairs the affected breaks with local search under the same rules.
  3. The new log goes to automation as an update; displaced spots enter the makegood queue.

Scaling

  1. Contention on hot inventory. Prime-time avails are sold by many people at once. Lever: short holds with expiry, conditional writes, per-break partitioning.
  2. Scheduling size. A network has many breaks and thousands of spots per day; exact MIP degrades (Bollapragada et al. report that exact and branch-and-bound methods fail on larger instances). Lever: decompose by day and break, heuristics, large neighborhood search.
  3. Ratings volume. Minute-level audience data for many targets. Lever: rollups into mergeable partial aggregates per order and week.
  4. Reconciliation latency. Days between log and reconciled as-run slows billing and makegoods. Lever: near-real-time as-run feeds (BXF status messages), exception-only review.
  5. Combined linear and programmatic sales. Auction latency is milliseconds, order commits are seconds. Lever: separate fast path with a shared, cached avail view.

Failure modes

FailureSymptomCauseFix
Oversold breakmore seconds sold than existraces on holds, stale cacheconditional commit; reservation as the only writer of remaining seconds
Duplicate orderadvertiser billed twiceclient retry without idempotencyidempotency keys on order mutations
Competitive clashtwo rival brands in one breakrule missing or overridden in a late changeconstraint check on every log publish, not only on first build
Wrong break boundarycommercial starts in programme or after itSCTE 35 PTS wrong, ad-insertion offset ignoredvalidate cues against the log; test against recorded streams
Missed as-runspot billed but not airedlog/as-run mismatchreconciliation exceptions, spot-level credit
Optimistic forecastrecurring audience deficiencybiased forecasts for new or declining showsbacktest bias, shrink forecasts, price deficiency risk
Time-zone and DST errorsbreaks shifted by an hourlocal time stored without zonestore UTC plus broadcast-day rules
Double-sold across linear and programmaticthe same seconds sold twiceseparate inventory viewsone inventory authority

Real implementations

Open-source linear TV traffic systems are rare; I found none to list. The open artefacts are standards and tooling around the system.

namewhat it isrepolicencenotes
WideOrbit, Operative, Imagine Communications, FreeWheelcommercial sell-side sales and traffic suites——named in the system graph's examples; closed source
SMPTE BXF (ST 2021 family)exchange of schedule, as-run and metadata between traffic and automation——documents at pub.smpte.org
OpenRTB 2.6auction protocol with CTV ad podsInteractiveAdvertisingBureau/openrtb2.x—IAB Tech Lab
Prebid Serveropen-source server for header-bidding auctionsprebid/prebid-serverApache-2.0programmatic side
TSDuckMPEG transport stream toolkittsduck/tsduckBSD-2-Clauseused for transport-stream work around cue messages
threefiveSCTE 35 parser and encoderfutzu/threefiveMITPython; parses and injects cues
scte35-spliceRust parser and builder for SCTE 35 2023r1fishloa/rust-broadcastMIT OR Apache-2.0crate scte35-splice
CasparCG Serverbroadcast graphics and playout serverCasparCG/serverGPL-3.0playout side

Sources

  • S. Bollapragada, H. Cheng, M. Phillips, M. Garbiras, M. Scholes, T. Gibbs, M. Humphreville, NBC's Optimization Systems Increase Revenues and Productivity, Interfaces 32(1), 2002. doi
  • S. Bollapragada, M. Garbiras, Scheduling Commercials on Broadcast Television, Operations Research 52(3), 2004. doi
  • S. Bollapragada, M. R. Bussieck, S. Mallik, Scheduling Commercial Videotapes in Broadcast Television, Operations Research 52(5), 2004. doi
  • SMPTE RP 2021-1:2019 (BXF requirements). pdf · TV Technology, BXF revealed as missing link
  • ANSI/SCTE 35 (Digital Program Insertion Cueing Message); summaries: Evrideo, scte35-splice docs
  • DVB, Targeted Advertising standards published by ETSI (TS 103 752). news
  • IAB Tech Lab, OpenRTB 2.6. spec
  • Digiday, WTF is the TV upfront? (guarantees, ADUs). article
  • Nielsen, Separating fact from fiction (C3/C7 as commercial ratings). page
  • Television reach and frequency in the United States, ESOMAR (beta-binomial, Metheringham variant). paper

Similar systems

Share the most building blocks with this one.