A private marketplace deal adds around 150 bytes to a bid request

Insights, Updates21 Sep 2026Damian Naglak
Half the questions in adtech are one question: is this in the list? The list is usually too big to keep, so the answer comes from something that trades a few wrong answers for the space. Has this person already seen the ad? Is this user in the segment? Is this domain on the blocklist? Is this a request the buyer would skip? Frequency capping, targeting, brand safety and traffic shaping ask four different questions with the same shape underneath: a set that's expensive to hold, checked millions of times a second. The answer is older than programmatic, and it comes down to not keeping the list at all. Picture a row of a thousand empty boxes. To put user 4471 on the list, the ID runs through a bit of arithmetic that always points at the same three boxes, say 12, 340 and 807, and those get ticked. Put user 9982 on and it points at 340, 512 and 903, so those get ticked too. Box 340 is now ticked by both of them, and nothing anywhere records which user did it. Checking works the same way. User 4471 points at 12, 340 and 807, all ticked, so 4471 is probably on the list. User 5000 points at 88, 512 and 640, and 88 is blank, so 5000 was definitely never added. Then user 7231 points at 12, 340 and 903, every one of them ticked by somebody else, so the answer comes back yes for a user that was never put on the list. One blank box and the answer is no, for certain. Every box ticked and the answer is probably yes. A user ID written out is 36 characters, so ten million of them is 360 megabytes stored as they are, or 160 packed into raw bytes. Compress that as hard as it can possibly go and it is still 133. The same ten million as ticks is 12 megabytes at one wrong yes in a hundred, 6 at one in ten, 18 at one in a thousand. This only works where a wrong yes is cheap. On a drop list it is. If the filter says a request is on the list when it never was, a few requests go unsent that didn't need to be, and sending fewer was the point anyway. Elsewhere in adtech the same mistake costs more or less depending on where it happens. Blocking a page that was actually fine is the cheap kind of mistake, and skipping someone who hadn't seen the ad yet only costs a bit of reach. Putting someone in an audience they were never in is the expensive one, because money goes on showing them the ad.

Most inventory trades through deals now, and the reasons given are commercial: price, access, guarantees. But what does a deal add to the anatomy of a bid request? One object on the impression, around 150 bytes.

A deal travels inside the ordinary bid request, through the same auction, as one extra object hanging off the impression. It’s called imp.pmp, it holds a flag and an array of deals, and everything PMP means commercially is carried in there.

What’s in a deal is mostly overrides. It carries its own floor, which replaces the floor on the impression, and its own currency, which doesn’t inherit from the impression and defaults to USD when nobody sets it. It can override the auction type for itself alone, and one of those values means the floor is the agreed price rather than a minimum. It can name the seats and advertiser domains allowed to bid, making a deal an access list as well as a price. One more field marks the deal guaranteed, which tells the bidder it’s expected to bid. That’s nine fields, two of them only for video and audio, where the floor changes with creative length.

I measured what all that weighs on a day of live bid requests, and the size is linear. One deal is 152 bytes, about 41 of that the wrapper, and every deal after the first adds another 110. Against a request averaging 2.7KB, a single deal is just under 6 percent of everything sent.

Say an exchange runs 500,000 requests a second and a third of those carry one deal. That’s a bit over two terabytes a day in deal objects by themselves, before compression, and about 800 terabytes a year on one buyer connection. The sender pays it. The receiver doesn’t, because cloud ingress is free, so on the buy side a deal costs decode time instead. Inside a containerized bidder those bytes obey different laws of physics. The bidder sits in the exchange’s own cluster, nothing crosses a network boundary, and the egress on all of it goes to zero. Everything two companies agree about a deal has to survive the trip into those nine fields. Price fits, access fits because wseat and wadomain name who is allowed to bid, and a guarantee gets one flag.

The share of spend moving through deals keeps climbing. Whether that continues, or agentic audiences take some of it back, is the open question. Vectors may end up carrying enough of what a buyer wants to replace part of what a deal does today.