Programmatic broadsheet · Set in real time
adon3
The Real-Time Bidding Exchange
Supply

Ad Call Latency: What Bidder Timeouts Cost Publishers

Your auction clears in 37 milliseconds. Your ad call does not. Here is where the other 600 milliseconds go, why the slowest bidders are often the ones bidding highest, and how a late creative quietly costs you twice — once at the auction and again in your Core Web Vitals.

CirculateXLinkedInEmail

There is a number most publishers never look at, and it explains more revenue variance than the one they check every morning.

It is not eCPM. It is not fill. It is the share of invited bidders that answered too late to be counted.

A bidder that responds one millisecond after your timeout window has closed is not recorded as a low bid. It is not recorded as a no-bid either. It is recorded as a timeout: a distinct state, a bidder that was invited to price your impression and never made it to the table. The auction cleared without it. Whatever it would have paid, you will never know.

This dispatch covers the mechanic that produces those timeouts, where your milliseconds actually go, why the slowest bidders are frequently the ones with the most money behind them, and what a late-arriving creative does to your page long after the auction has settled.

The timeout mechanic, in order

An ad call is not one request. It is a chain of nested requests, each one operating inside the time budget of the one above it.

1. The page calls your supply partner. A tag, wrapper or SDK on your page fires a request. The clock starts here, from the user's perspective, and that is the only perspective that matters for page speed.

2. Your supply partner calls the exchange. The request is translated into an OpenRTB bid request. Inside that request is a field called tmax: the maximum number of milliseconds the caller is prepared to wait for a response. It is a declaration, not a suggestion.

3. The exchange calls its bidders. The exchange now has its own budget: whatever tmax it was given, minus the time already spent, minus what it needs to run the auction and return. It sets a shorter tmax on each outbound call to the DSPs. Each hop nests inside the one before it, and each hop shrinks the window.

4. Bidders respond, or do not. Every DSP that answers inside the window enters the auction with a price. Every DSP that answers outside it is discarded. The response may be well-formed, may contain the highest bid on the floor, may have been three milliseconds late. It is discarded all the same, and written to the log as a timeout.

5. The auction clears. Highest eligible bid wins. On Adon3 this step takes roughly 37 milliseconds.

6. The creative loads. The winning ad markup returns to the page, and the browser fetches the actual asset (image, video, script) from what is often a completely different domain, one that has not yet been resolved.

Step 5 is fast and predictable. Steps 1, 2, 4 and 6 are where the time goes, and steps 4 and 6 are where your money goes.

The critical thing to internalise: the timeout is enforced by whoever is waiting, not by whoever is late. A slow bidder does not know it was slow. It sends its response, gets no acknowledgement, and moves on. Only the caller records the event. Which means the timeout rate lives in your logs, and nowhere else.

Where the milliseconds actually go

Publishers who measure their ad call at all tend to measure it once, from a fast office connection on a warm cache, and conclude everything is fine. The number that matters is the one your median mobile visitor experiences on a cold load.

Here is a realistic budget for that visitor. Treat the ranges as illustrative. Yours will differ by geography, device and stack, but the shape holds.

Stage

Cold load

Warm load

Notes

DNS resolution (ad domain)

20–120 ms

~0 ms

Fixable with dns-prefetch

TCP + TLS handshake

60–200 ms

~0 ms

Two to three round trips

Consent gate resolution

0–800 ms

0–100 ms

Often the single largest block

Request to supply partner

20–150 ms

20–150 ms

Depends on POP proximity

Exchange auction

~37 ms

~37 ms

Bounded by tmax

Response back to page

20–150 ms

20–150 ms

Same path, in reverse

Creative fetch

50–400 ms

20–100 ms

New domain, new handshake

Render + main thread work

20–300 ms

20–300 ms

Heavy scripts compete with your page

The auction is the cheapest thing in the table. On a cold mobile load, a 37-millisecond auction can sit inside a 900-millisecond ad call, and every millisecond of that call is a millisecond your reader is looking at an empty box.

Three lines in that table deserve individual attention.

The consent gate. On most European and UK traffic, no ad call fires until the consent management platform has loaded, evaluated and returned a signal. If your CMP is loaded late, or loaded after other blocking scripts, it delays every downstream step. Publishers frequently spend weeks tuning bidder timeouts while a 600-millisecond CMP sits upstream of the entire chain, untouched.

The creative fetch. The auction returns markup, not an image. The browser then has to resolve a new hostname, complete a new handshake and download the asset. This step is invisible in most ad-server reporting, which stops counting at the response, and it routinely costs more time than the auction it followed.

Geography. Your tmax is the same for every visitor. The network is not. A bidder that answers in 90 milliseconds for traffic in Frankfurt may answer in 240 for traffic in Jakarta or Lagos. Same bidder, same infrastructure, same window, and a timeout rate that varies by an order of magnitude across your geo mix. This is a large part of why some publishers conclude tier-3 traffic "does not monetise". It monetises. It is simply timing out.

Why the slowest bidders are often the richest

If timeouts removed bidders at random, the revenue cost would be modest. They do not.

Consider what a DSP is doing inside its response window. A bidder that fires back a flat, untargeted price at 40 milliseconds is doing almost no work: it has a broad campaign, a fixed CPM, and no reason to look anything up. A bidder that takes 180 milliseconds is usually taking that time because it is doing something: resolving an identifier, checking a retargeting segment, querying a frequency cap, running a pacing model against a CPA goal.

That second bidder is doing work because the impression might be worth more to it. Retargeted and audience-matched demand is precisely the demand that pays above your floor. Timeouts are not a random tax on your auction. They preferentially remove the bidders most likely to have outbid everyone else.

The effect compounds through the auction itself. Clearing prices rise with the number of genuine competing bids, and they rise fastest in the low counts. The gap between two bidders and five is large. The gap between eight and eleven is small. If your timeout rate is pulling a typical auction from six responders down to three, you are not losing a third of your competition. You are losing the part of the distribution where the price gets set.

A worked illustration. Ten bidders invited on a given placement:

  • Tight window (100 ms): 5 respond, 5 time out. Top bid $1.90, clears at $1.90.

  • Wider window (220 ms): 8 respond, 2 time out. Top bid $2.65, clears at $2.65.

That is a 39% difference in clearing price on identical inventory, produced entirely by 120 milliseconds of patience. The three bidders recovered were the three doing lookups.

Which raises the obvious question, and the obvious trap.

Why you cannot simply set the timeout to two seconds

If a wider window recovers higher bids, the temptation is to widen it until the recovery stops. That fails, for four separate reasons, and the failures do not show up in your eCPM column.

Viewability collapses. An ad that renders after the reader has scrolled past it is measurable but not viewable. Your viewability rate falls. Buyers who filter on viewability, which is most of the ones paying well, either bid down or stop bidding on your inventory altogether. This is the worst kind of damage because it is delayed and it is sticky: you fix the latency in March and the bids do not come back until buyers' models have re-learned your inventory in May.

Layout shift. A creative arriving 800 milliseconds late into a slot without reserved dimensions pushes your content down the page as the reader is trying to read it. Late ad arrival is the single most common cause of ad-driven Cumulative Layout Shift, and CLS is a ranking signal. You are trading search traffic for clearing price.

Abandonment. Some proportion of readers leave before the ad renders at all. Those impressions are never billable, and the reader was on your page for the whole latency period, contributing nothing and enjoying it less.

The compounding effect on total revenue. Publisher revenue is roughly pageviews × impressions per session × eCPM. Latency degrades all three simultaneously. A slow page reduces pages per session, which reduces impressions, which reduces revenue on inventory that was priced perfectly well. Optimising eCPM in isolation can lose you money in total, and the reporting will show the eCPM improvement quite clearly while the pageview decline hides in a different dashboard.

The window has an optimum. It is not the widest value, and it is not the tightest. It is specific to your placement, your geography and your bidder set, and you find it by measuring rather than by guessing.

Finding your number: a diagnostic sequence

Work through this in order. Each step is cheap, and most publishers find the problem before step five.

1. Measure the real ad call, on real traffic. Use the browser's Resource Timing API to capture the full duration from tag fire to creative render, on live sessions, segmented by device and connection type. Not a lab test. Not your laptop.

javascript

// Rough field measurement. Log to your own analytics endpoint.
performance.getEntriesByType('resource')
  .filter(r => r.name.includes('your-ad-domain'))
  .forEach(r => {
    console.log(r.name, {
      dns:   Math.round(r.domainLookupEnd - r.domainLookupStart),
      tcp:   Math.round(r.connectEnd - r.connectStart),
      ttfb:  Math.round(r.responseStart - r.requestStart),
      total: Math.round(r.duration)
    });
  });

2. Pull timeout rate per bidder from the request logger. Not the average. The distribution. You want p50, p90, p95 and p99 response time for each endpoint, and the percentage of calls that exceeded your window. On Adon3 this is in the request logger; on other stacks it may be an analytics add-on you have to enable.

3. Segment by geography. Sort your timeout rate by country. If one region shows two or three times the timeout rate of the rest, you have found a routing problem, not a bidder problem, and no amount of timeout tuning will fully fix it.

4. Segment by device and network. Mobile adds latency at every stage. If your timeout window was set on desktop data and 70% of your traffic is mobile, it is set wrong for the majority of your inventory.

5. Check what tmax is actually being enforced. Publishers set a value in their wrapper configuration and assume it propagates. Frequently it does not: a global failsafe overrides it, or an intermediary rewrites it downward to protect its own budget. Verify against the logs rather than against the config file.

6. Count your hops. Every reseller between your page and the buyer adds a network round trip and shrinks the window available to the bidder at the end of it. A four-hop path can leave the final DSP with 60 milliseconds of a 200-millisecond budget. Read your schain and see how long the path actually is. Shortening the chain is the only latency fix that also improves your price for a second, independent reason: fewer intermediaries taking a margin.

The fixes, ranked by return on effort

Immediate, one line each:

html

<link rel="dns-prefetch" href="//your-ad-domain.com">
<link rel="preconnect" href="//your-ad-domain.com" crossorigin>

Resolve DNS and complete the TLS handshake before the ad call needs them. On cold mobile loads this alone commonly returns 80 to 200 milliseconds. Add one pair for each ad domain that appears in a typical page load, including creative-serving domains. Keep the list short though, since each preconnect holds an open connection.

Reserve every slot's dimensions. Fixed min-height on the container. This does not speed anything up; it means a late creative lands in a hole that was already there instead of shoving your article down the page. It fixes ad-driven CLS almost entirely, independent of any latency work.

Load ad tags asynchronously, and move the consent gate first. No ad script belongs in a synchronous position in <head>. The CMP, on the other hand, belongs as early as possible, because everything else waits for it.

Set timeouts per endpoint, not globally. One window for all bidders means the window is wrong for most of them. Set each endpoint's window near the p90 of its own observed response time. Bidders that answer fast get a tight window; bidders that answer slowly but pay well get the room they need.

Then test in increments, and measure four things at once. Move the window 100 milliseconds at a time. At each step record eCPM, viewability rate, CLS and pages per session. Accept the change only if the revenue gain survives contact with the other three. Give each test at least a full week. Ad performance has a strong day-of-week pattern, and a Tuesday-to-Thursday test will tell you almost nothing.

Shorten the supply path. Each hop removed returns latency and margin simultaneously. This is the reason a direct exchange connection outperforms the same demand reached through two resellers even when the underlying buyers are identical.

The short version

Your auction is not slow. The auction is 37 milliseconds and it is the most predictable part of the entire sequence. What is slow is everything wrapped around it: the handshake nobody pre-warmed, the consent gate loaded fourth instead of first, the creative fetched from an unresolved domain, and the four-hop supply path that left the final bidder 60 milliseconds to make a decision.

The bill arrives in two places. At the auction, as bidders discarded for lateness, and disproportionately the bidders that were taking their time because the impression was worth something to them. And on the page, as layout shift, lost viewability and readers who left before the ad arrived.

Both are measurable. Start with the timeout rate per bidder in your logs, sorted by geography. The answer is usually sitting in the first three rows.


Adon3 clears auctions in roughly 37 milliseconds and records every timeout, per endpoint, in the request logger, including the responses that arrived too late to count. Open a publisher account, or read the integration docs for the timeout and endpoint configuration reference.

Related: What Is a Pop-Under Ad? A Publisher's Guide to How It Actually Works

FAQ

What is tmax in OpenRTB? tmax is a field in the bid request stating the maximum time in milliseconds the caller will wait for a bid response. Responses arriving after it are discarded and logged as timeouts rather than as bids.

What is a good ad call timeout for publishers? There is no universal value. Set it per endpoint near the 90th percentile of that endpoint's observed response time, then test in 100 ms increments while watching eCPM, viewability, CLS and pages per session together.

Do ads affect Core Web Vitals? Yes. Late-arriving creatives in unreserved slots are a leading cause of Cumulative Layout Shift, and heavy ad scripts compete for main-thread time, affecting Interaction to Next Paint. Reserving slot dimensions addresses most ad-driven CLS.

Why do bidders time out? Usually network distance, a supply chain with too many hops leaving little budget for the final bidder, or a bidder performing identity, segment and pacing lookups that legitimately take longer. The last group often carries the highest bids.

Does a longer timeout always mean more revenue? No. Wider windows recover high-value bids but cost viewability, increase layout shift and lose readers who leave before render. Total revenue can fall while eCPM rises.

Filed1 September 2026
Last revised1 September 2026
Length2,539 words · 13 min
Written by
Garry Williams
CirculateXLinkedInEmail
sellers.json · schain enforced · OpenRTB 2.5 / 2.6 / 3.0 · XML
Printed on the Open Exchange
—  Supply  —