Somebody taps a link to your article on their phone. By the time the headline is readable, an auction has already happened. Dozens of companies were asked whether they wanted to show that person an ad, most said no, a few said yes with a price attached, one of them won, and money moved.
All of it inside roughly a fifth of a second.
Most publishers never see this sequence described in order. You see the output, which is a CPM in a dashboard, and you are left to reverse-engineer why that number went up or down. So here is the whole thing, in the order it happens, in plain terms.
t = 0ms — the page starts loading
Your page begins rendering and your ad tags fire. If you are running header bidding, a small piece of JavaScript wakes up and starts organising an auction on the visitor’s own device before your ad server is even asked what to show.
This is worth pausing on, because it is the part people get wrong most often. The auction is not happening on a server somewhere in the abstract. The first phase runs in your reader’s browser, on their connection, using their battery. Every millisecond you spend here is a millisecond of their attention you are borrowing.
t = 5ms — the bid request gets assembled
A bid request is built. It is a JSON object, and if you have never seen one, it is less mysterious than it sounds. It says roughly: here is a 300×250 slot, on this domain, on this page, on an iPhone running Safari in Germany, the user has given consent under these terms, the floor price is 42 cents, and you have 500 milliseconds to reply.
What goes into that object determines what you get paid. A request that accurately declares the domain, the placement position, the ad format and the geography will attract higher bids than one that is vague or wrong. Buyers price uncertainty as risk, and risk is discounted.
This is also where ads.txt becomes real money rather than housekeeping. A buyer receiving your request checks whether the party selling it is actually authorised by you. If the answer is no, or unclear, a lot of demand simply will not bid.
t = 12ms — the request fans out
The request now goes to every exchange and SSP you have integrated, and each of those forwards it to the DSPs connected to them. One page view becomes hundreds of bid requests within a few milliseconds.
Here is the uncomfortable part. Most of those requests are never going to result in a bid. A DSP receiving your request checks it against every active campaign it holds, and for the overwhelming majority the answer is no in under a millisecond. Nobody is targeting that user, or the floor is too high, or the category is blocked.
A bid rate in the low single digits is completely normal. If ninety-seven out of a hundred requests come back empty, nothing is broken.
t = 48ms — bids start coming back
The DSPs that do want the impression respond with a price, a creative, and a set of conditions. A response might say: I will pay $1.84 CPM for this, here is the ad, and here is a URL to ping if I lose.
Two things decide how much money arrives at this moment.
How many buyers are actually competing. Not how many are connected. Connected is a slide in a deck. Competing means they received the request, wanted it, and bid. Two genuine bidders will beat twenty nominal integrations every time.
Whether they trust what they are looking at. A buyer who cannot verify your inventory bids cautiously or not at all.
t = 92ms — the timeout closes
Every auction has a deadline, sent in the request as tmax. When it expires, whatever has arrived is what gets counted. Anything late is discarded, however high the bid.
This is the single most consequential setting most publishers never touch, and the tradeoff runs in both directions. Set the timeout too short and you cut off slower bidders, some of whom would have paid the most. Set it too long and the page sits there waiting while your reader looks at empty space, which costs you in Core Web Vitals and in people leaving.
There is no universal correct number. It depends on where your readers are, what devices they use, and how your partners are integrated. What I would say with some confidence is that a default nobody has ever revisited is usually leaving money somewhere.
t = 140ms — the auction resolves
The highest bid wins. In a first-price auction, which is now the norm, the winner pays what they bid. Under the old second-price model they paid a penny above the runner-up, which is why CPM comparisons across that transition are not meaningful.
The winning creative is returned to the page. Losing bidders get a loss notice, ideally with a reason code attached, so their systems learn what happened. Whether you actually receive those loss reasons is a reasonable thing to ask your partners about, and the answer tells you something about how they operate.
t = 200ms — the ad renders, and you have been paid
The creative loads. An impression is counted, provisionally. Somewhere in a ledger, a fraction of a cent is now owed to you.
Provisionally is doing work in that sentence. The impression still has to survive viewability measurement and invalid-traffic filtering before it becomes money you keep. That is a separate process and a separate article.
What this means for you on a Tuesday morning
Once you can see the sequence, dashboard numbers stop being weather and start being diagnosable.
- CPMs dropped but traffic is flat. Look at competition, not volume. Did a buyer pause budget? Did a partner start filtering your requests?
- Fill rate is fine but revenue is not. Your floor is probably too low and you are selling cheaply to whoever shows up first.
- Both are fine but the site feels slow. Your timeout, or the number of partners you have loaded into the page, is costing you readers to buy marginal bids.
- Everything is fine on desktop and poor on mobile. Mobile connections make timeouts bite harder. The same setting behaves differently on 4G.
None of this requires you to become an engineer. It requires knowing that between a tap and an ad there is a sequence with specific steps, each of which can be inspected and adjusted.
The publishers who earn the most from the same traffic are usually not the ones with the most partners. They are the ones who know which step is currently costing them.
