intermediate

How an RTB Auction Works

The OpenRTB request/response cycle end to end — what is in a bid request, how a DSP prices it in under a millisecond, and what the 100ms timeout really constrains.

3 min readUpdated Nov 10, 2026By AdTechDocs

Assumed knowledge

Impression, DSP, SSP, Ad Request

On this page

Real-time bidding is a market that clears once per impression, on a deadline measured in milliseconds, between parties who never speak to each other. This page follows one impression all the way through.

The request

When a slot becomes available, the exchange constructs an and fans it out to every connected buyer. Trimmed to the fields that actually drive pricing, it looks like this:

bid-request.json
{
  "id": "8f2a1c4e-7b3d-4a91-9e6f-2c5d8b1a3f74",
  "at": 1,
  "tmax": 120,
  "imp": [
    {
      "id": "1",
      "banner": { "w": 300, "h": 250, "pos": 1 },
      "bidfloor": 1.45,
      "bidfloorcur": "USD",
      "secure": 1
    }
  ],
  "site": {
    "domain": "example-news.com",
    "page": "https://example-news.com/markets/article-123",
    "cat": ["IAB13"],
    "publisher": { "id": "pub-4471" }
  },
  "device": {
    "ua": "Mozilla/5.0 ...",
    "geo": { "country": "USA", "region": "NY" },
    "devicetype": 2,
    "os": "macOS"
  },
  "user": { "buyeruid": "a7f3...", "consent": "CPx..." },
  "regs": { "gdpr": 0, "us_privacy": "1YNN" }
}

Four fields deserve attention, because they determine almost everything:

  • tmax — the timeout in milliseconds. Answer later than this and your bid is discarded, having cost you the compute anyway.
  • at — auction type. 1 is first price, 2 is second price. Read it; do not assume it.
  • bidfloor — the . Bid under it and you are ignored.
  • pos — ad position. 1 means above the fold, which correlates strongly with whether the ad will ever be viewable.

The response

The DSP has tmax milliseconds, minus network round-trip, to decide. In practice that leaves 40 to 80 milliseconds of wall clock — and because one DSP handles hundreds of thousands of these per second, roughly one millisecond of CPU per decision.

In that millisecond it must:

  1. Filter. Which active campaigns are even eligible — geography, device, category block lists, frequency cap, remaining budget.
  2. Predict. For each eligible campaign, the probability this impression produces the outcome being bought. A click-through or conversion rate model, inferred from features in the request.
  3. Value. Multiply that probability by what the advertiser pays per outcome. A 0.2% predicted conversion rate on a $50 target CPA implies $0.10 per impression, which is a $100 CPM — before any adjustment.
  4. Price. Decide what to actually bid, which is not the value. See below.
bid-response.json
{
  "id": "8f2a1c4e-7b3d-4a91-9e6f-2c5d8b1a3f74",
  "seatbid": [
    {
      "seat": "dsp-seat-22",
      "bid": [
        {
          "id": "bid-1",
          "impid": "1",
          "price": 2.87,
          "adm": "<script src=\"https://cdn.example-dsp.com/c/9931.js\"></script>",
          "adomain": ["brand.example"],
          "crid": "creative-9931",
          "cat": ["IAB19"],
          "w": 300,
          "h": 250
        }
      ]
    }
  ],
  "cur": "USD"
}

adomain is not optional decoration. It is how a publisher enforces its own advertiser block list, and a response that omits or falsifies it gets a seat suspended.

Clearing the auction

The exchange collects whatever arrived before the timeout, discards anything below the floor or violating a publisher block, and ranks the rest.

Under — now the default for display — the winner pays exactly what it bid. Under second price it pays one cent above the runner-up.

That difference changes bidder behaviour completely, and the fastest way to feel it is to run it:

Auction simulator

Move the controls and watch who wins and what the publisher keeps.

  • DSP A
    $7.40
    won
  • DSP B
    $5.90
  • DSP C
    $4.20
  • DSP D
    $2.80
Floor
$1.00
Winner
DSP A
Advertiser pays
$7.40
Intermediary fees
$1.48
Publisher keeps
$5.92
$1.00

Raise it past the top bid to see a no-fill.

0%

Buyers discounting their true value under first price.

20%

Combined cut of every intermediary in the path.

Under first price the winner pays its own bid, so bidding true value overpays — which is why shading exists.

Push the floor above every bid and you get a no-fill: the slot goes unsold, the publisher earns nothing, and a passback or house ad fills the space. Floors are a revenue optimisation with a real downside, which is why dynamic floors — recalculated per request from predicted demand — replaced static ones almost everywhere.

Where the time actually goes

The 100ms budget is not spent where newcomers expect.

StageTypical budget
Network, exchange → DSP → exchange30–60ms
DSP filtering and model inference5–15ms
Exchange auction and response assembly5–10ms
Creative fetch and render in the browser100–400ms

Two conclusions follow. First, the network dominates, which is why bidders deploy into the same regions as the exchanges they serve and why adding a hop to the supply path has a measurable cost in win rate. Second, rendering dwarfs bidding. A buyer obsessing over 3ms of inference while shipping a 900KB creative has misread the problem.

Check yourself

A DSP consistently returns bids at 140ms against a tmax of 120. What happens?

Key takeaways

  • A bid request is an untrusted description of an impression; validate it against ads.txt and your own seller-level performance data.
  • Read `at` and `bidfloor` on every request — assuming second price under a first-price auction is how buyers systematically overpay.
  • A DSP has roughly one millisecond of CPU per decision, which constrains model complexity far more than accuracy does.
  • Network latency dominates the bidding budget, and creative rendering dominates the total.
  • A late bid is worth exactly as much as no bid, and costs the same as a winning one.

Next

First Price and the Rise of Bid Shading picks up at step 4, where valuation becomes pricing.