RTB Architecture

    Demand path optimization for publishers: measure every path, then test the cut

    Published · Last updated
    Next scheduled review:

    Demand path optimization is the publisher's answer to buyers' supply path optimization. You measure every route by which demand reaches your inventory. Then you remove or demote the routes that add fees and duplicate requests without adding unique bids. This guide covers why buyers trim paths, which metrics to track per path and how to test a cut safely.

    Contents

    Key facts

    • ads.txt already labels your paths. In ads.txt 1.1, DIRECT means the publisher "directly controls the account", while RESELLER means it has "authorized another entity to control the account and resell" its ad space (IAB Tech Lab, ads.txt 1.1).
    • Buyers see the same impression many times. The Trade Desk's Will Doherty said some supply-side platforms (SSPs) send 30% of a publisher's traffic "and they send it three times" (AdExchanger, 17 January 2024).
    • Most chains fail a full check. A HUMAN Security diagnostic found 79% of bid requests carried a SupplyChain object, but only 42% of those objects passed full validation (PPC Land, 6 September 2026).
    • Buyers cap what they listen to. Index Exchange estimates about 10 million queries per second (QPS) across the internet, with each demand-side platform (DSP) capping its intake at around 1 to 3 million (Index Exchange, accessed 9 November 2026).
    • Direct buyer paths now have a price tag. The Trade Desk charges publishers a flat 4.5% fee for OpenPath, its direct publisher connection (PPC Land, 2 July 2026).
    • Concentrated buyers do better. In the ANA's Q2 2026 benchmark, higher-performing advertisers bought across about 19,000 fewer domains and apps than lower performers (Fiducia on ANA, 6 August 2026).
    Jump to the table

    Definition

    Demand path optimization (DPO): the sell-side practice of listing every route from a publisher's inventory to buyers and measuring each route's unique bids, cost and data quality. The publisher then removes, merges or demotes the routes that duplicate others or erode trust.

    It mirrors supply path optimization (SPO), which buyers run on their side. Both look at the same chain: publisher, SSP or exchange, any resellers, then the DSP. The difference is who holds the knife. If you do not prune your own paths, buyers will prune them for you, usually by dropping the paths they like least. This page sits in the publisher independence hub.

    Why buyers run SPO, and what it does to your paths

    Buyers trim paths for three reasons. Duplicate requests waste their QPS budget. Every extra hop takes a fee from the media dollar. And long, unverifiable chains look like fraud risk.

    Duplication comes straight from header bidding. You ask every SSP to auction the same impression, and each one may send it to every DSP. AdExchanger described buyers sifting "dozens of duplicate bid requests" that look identical (AdExchanger, 17 January 2024). A DSP that caps intake at 1 to 3 million QPS cannot listen to all of them, so it keeps the paths it trusts (Index Exchange). The commercial side of those caps is covered in QPS, latency and bid performance.

    Buyers also reward short paths with money. The ANA's Q2 2026 benchmark shows the best-performing advertisers buying on far fewer domains and apps (Fiducia on ANA, 6 August 2026). The Trade Desk built OpenPath to buy from publishers without an SSP in between. Its chief executive has cited Hearst Newspapers' fourfold fill-rate gain and 23% revenue increase, and a 97% rise in programmatic display revenue at the New York Post (company claims, PPC Land, 2 July 2026).

    The lesson for a publisher is not "fewer partners is always better". It is that each path must earn its place with bids nobody else brings.

    The demand paths a typical publisher runs

    Start with an inventory. Most publishers have more paths than they think, because one SSP can appear several times: once as a direct seller, again behind a reseller and again inside a curated deal.

    5 of 5 rows

    Columns (5)

    SSP, direct account

    ads.txt DIRECT; sellers.json seller_type PUBLISHER; one schain node

    0

    Low

    Unique bids per auction

    SSP through a reseller

    ads.txt RESELLER; sellers.json INTERMEDIARY; two or more nodes

    1 or more

    Fee stacking, buyer blocklists

    Whether the reseller adds buyers you lack

    Same SSP twice (client and server)

    Two requests with the same source.tid or none

    0, but duplicated

    Self-competition, wasted QPS

    Deduplication and win overlap

    Curated or private marketplace deal

    DIRECT or RESELLER, plus a deal ID

    0 to 1

    Curator fee on top of SSP fee

    Net price after all fees

    Direct DSP connection

    Publisher-declared path into one DSP

    0

    Dependence on one buyer

    Fee versus the SSP path it replaces

    SSP, direct account

    How buyers see it

    ads.txt DIRECT; sellers.json seller_type PUBLISHER; one schain node

    Extra hops

    0

    Main risk

    Low

    What to check

    Unique bids per auction

    SSP through a reseller

    How buyers see it

    ads.txt RESELLER; sellers.json INTERMEDIARY; two or more nodes

    Extra hops

    1 or more

    Main risk

    Fee stacking, buyer blocklists

    What to check

    Whether the reseller adds buyers you lack

    Same SSP twice (client and server)

    How buyers see it

    Two requests with the same source.tid or none

    Extra hops

    0, but duplicated

    Main risk

    Self-competition, wasted QPS

    What to check

    Deduplication and win overlap

    Curated or private marketplace deal

    How buyers see it

    DIRECT or RESELLER, plus a deal ID

    Extra hops

    0 to 1

    Main risk

    Curator fee on top of SSP fee

    What to check

    Net price after all fees

    Direct DSP connection

    How buyers see it

    Publisher-declared path into one DSP

    Extra hops

    0

    Main risk

    Dependence on one buyer

    What to check

    Fee versus the SSP path it replaces

    Download JSON

    Table by AdSovereign, CC BY 4.0.

    Definitions in the first two columns come from the ads.txt 1.1 and sellers.json specifications. The other columns are our design rules. The join keys between the three files are explained in SupplyChain object, ads.txt and sellers.json together.

    Metrics per path: bid density, win rate and take rate

    Measure paths, not partners. An SSP that is excellent as a direct path can be poor behind a reseller. Each metric below needs one row per path per day, built from your wrapper and ad server logs.

    7 of 7 rows

    Columns (4)

    Bid density

    Bids received ÷ auctions the path joined

    Wrapper bid events

    How much demand the path brings

    Unique bid share

    Auctions where only this path bid ÷ auctions it joined

    Wrapper bid events, joined by auction

    Demand you lose if you cut it

    Impressions won ÷ bids received

    Ad server and wrapper win events

    Whether its bids are competitive

    Net eCPM

    Publisher revenue ÷ impressions won × 1,000

    SSP payments, ad server

    Price after the path's fees

    (Buyer spend − publisher revenue) ÷ buyer spend

    Log-level data from the buyer, or SSP fee terms

    Share of each dollar kept by the path

    Duplicate rate

    Requests sharing an auction ID with another path ÷ requests

    Bid request logs

    Self-competition and wasted QPS

    Timeout rate

    Bids arriving after the wrapper timeout ÷ bids

    Wrapper events

    Latency cost of keeping the path

    Bid density

    Formula

    Bids received ÷ auctions the path joined

    Data source

    Wrapper bid events

    What it tells you

    How much demand the path brings

    Unique bid share

    Formula

    Auctions where only this path bid ÷ auctions it joined

    Data source

    Wrapper bid events, joined by auction

    What it tells you

    Demand you lose if you cut it

    Win rate

    Formula

    Impressions won ÷ bids received

    Data source

    Ad server and wrapper win events

    What it tells you

    Whether its bids are competitive

    Net eCPM

    Formula

    Publisher revenue ÷ impressions won × 1,000

    Data source

    SSP payments, ad server

    What it tells you

    Price after the path's fees

    Take rate

    Formula

    (Buyer spend − publisher revenue) ÷ buyer spend

    Data source

    Log-level data from the buyer, or SSP fee terms

    What it tells you

    Share of each dollar kept by the path

    Duplicate rate

    Formula

    Requests sharing an auction ID with another path ÷ requests

    Data source

    Bid request logs

    What it tells you

    Self-competition and wasted QPS

    Timeout rate

    Formula

    Bids arriving after the wrapper timeout ÷ bids

    Data source

    Wrapper events

    What it tells you

    Latency cost of keeping the path

    Download JSON

    Table by AdSovereign, CC BY 4.0.

    Unique bid share is the metric most publishers skip, and it decides most cuts. A path with low bid density but high unique share is worth keeping. A path with high density and near-zero unique share is a duplicate that buyers will eventually drop.

    Take rate is the hardest number to get. You see your own revenue, not the buyer's spend. Buyers with log-level data can compute it, and some SSPs share it under contract. The ANA counts SSP and DSP fees together as transaction costs, which reached 27.2% of tracked spend in Q2 2026 (Fiducia on ANA, 6 August 2026).

    A path record you can compute daily

    The record below is our schema, not a standard. Field names are ours and the values are illustrative.

    {
      "date": "2026-11-08",
      "path_id": "ssp-b.example/reseller-c.example",
      "ads_txt_relationship": "RESELLER",
      "sellers_json_seller_type": "INTERMEDIARY",
      "schain_nodes": 2,
      "schain_complete": true,
      "auctions_joined": 4200000,
      "bids_received": 630000,
      "auctions_only_this_path_bid": 21000,
      "impressions_won": 52000,
      "publisher_revenue_usd": 78.0,
      "buyer_spend_usd": 104.0,
      "duplicate_requests": 1900000,
      "late_bids": 41000,
      "metrics": {
        "bid_density": 0.15,
        "unique_bid_share": 0.005,
        "win_rate": 0.0825,
        "net_ecpm_usd": 1.5,
        "take_rate": 0.25,
        "duplicate_rate": 0.4524,
        "timeout_rate": 0.0651
      }
    }

    5 of 5 rows

    Columns (2)

    ads_txt_relationship, sellers_json_seller_type

    Copied from your ads.txt line and the SSP's sellers.json entry for this seller ID

    schain_nodes, schain_complete

    Read from source.schain in the bid request, as defined in OpenRTB 2.6

    auctions_only_this_path_bid

    The numerator of unique bid share; needs an auction-level join across paths

    buyer_spend_usd

    Often unknown; leave it null rather than guess, and take rate becomes null too

    metrics.unique_bid_share

    21,000 ÷ 4,200,000 = 0.5% in this example: a strong cut candidate

    ads_txt_relationship, sellers_json_seller_type

    Meaning

    Copied from your ads.txt line and the SSP's sellers.json entry for this seller ID

    schain_nodes, schain_complete

    Meaning

    Read from source.schain in the bid request, as defined in OpenRTB 2.6

    auctions_only_this_path_bid

    Meaning

    The numerator of unique bid share; needs an auction-level join across paths

    buyer_spend_usd

    Meaning

    Often unknown; leave it null rather than guess, and take rate becomes null too

    metrics.unique_bid_share

    Meaning

    21,000 ÷ 4,200,000 = 0.5% in this example: a strong cut candidate

    Download JSON

    Table by AdSovereign, CC BY 4.0.

    ads.txt, sellers.json and schain hygiene

    Buyers read your files before they read your bids. A path with a broken or missing declaration may be filtered out before any DSP prices it. Clean files are the cheapest DPO work you can do.

    1. Remove lines for partners you no longer use. Every stale RESELLER line is an authorised path someone can still sell through.
    2. Mark relationships honestly. Label a line DIRECT only when you hold the account and the contract, per the ads.txt 1.1 definition (IAB Tech Lab).
    3. Match sellers.json. Your seller ID should appear in each SSP's sellers.json with the right seller_type. A PUBLISHER entry on a path you call RESELLER is a mismatch buyers notice (IAB Tech Lab, sellers.json).
    4. Check that chains are complete. Ask each SSP for sample bid requests and confirm schain.complete is 1 and every node resolves. HUMAN's diagnostic found 98% of objects declared themselves complete, yet only 42% passed full validation (PPC Land, 6 September 2026).
    5. Review the file every month. Use the ads.txt generator to rebuild the file from a clean partner list instead of editing by hand.

    Removing a RESELLER line is itself a path cut. Treat it like one and test it, as described below.

    How to test a path cut without losing revenue

    Never cut a path everywhere at once. Revenue moves for many reasons, and a one-week drop after a cut proves nothing. Run a controlled test instead: keep the path for a control group of traffic and remove it for a test group.

    1. Pick the unit of randomisation. Page views are easiest. Use pages or geographic regions if buyers might shift spend between groups during the test.
    2. Split traffic with your wrapper. Prebid.js has a server-to-server testing module whose bidSource setting sends a bidder through the client or server path for a set share of requests. It adds an hb_source key-value so your ad server can report each group (Prebid.org, s2sTesting module).
    3. Fix the primary metric before you start. Use revenue per thousand page views (RPM) for the whole page, not the eCPM of one partner. A cut can lower one partner's eCPM while raising page revenue.
    4. Set guardrails. Stop the test if test-group RPM falls more than an agreed share for two days running, or if fill drops on a key placement.
    5. Run long enough to cover a buying cycle. Two full weeks covers weekday and weekend patterns; budget flight changes at month end need longer.
    6. Read the result per segment. Check desktop, mobile web, app and CTV separately, and top buyers separately. A cut can be neutral overall and harmful for one buyer.

    Prebid's own documentation warns that its testServerOnly flag turns off client bids for part of the traffic "and should be used with caution" (Prebid.org). The same caution applies to any cut: test on a small share first. Wrapper analytics for these tests are covered in Prebid Server analytics and debugging.

    A test plan in JSON

    This plan is our format, not a Prebid configuration. It records what you will cut, how traffic splits and when you stop. Values are illustrative.

    {
      "test_id": "dpo-2026-11-reseller-c",
      "hypothesis": "Removing reseller C does not lower page RPM because its bids are 99.5% duplicated by direct paths",
      "paths_removed_in_test_group": ["ssp-b.example/reseller-c.example"],
      "randomisation_unit": "page_view",
      "traffic_split": { "control": 0.8, "test": 0.2 },
      "primary_metric": "page_rpm_usd",
      "secondary_metrics": ["fill_rate", "bid_density_all_paths", "timeout_rate", "top_10_buyer_spend"],
      "guardrails": { "max_rpm_drop_pct": 3.0, "consecutive_days": 2, "action": "end_test_restore_path" },
      "duration_days": { "minimum": 14, "maximum": 28 },
      "segments": ["desktop_web", "mobile_web", "app", "ctv"],
      "decision_rule": "Cut if RPM change is within -1% and the 95% interval excludes -3%"
    }

    Worked example: two resold paths, one decision

    The numbers in this example are illustrative, not benchmarks. Suppose a news site runs SSP B directly and also through reseller C. Over 14 days the test group, without reseller C, earns $11.92 RPM and the control earns $11.95 RPM. That is a 0.25% drop, inside the 1% band in the plan. The split itself can run on Prebid's bidSource setting.

    The site also looks at what reseller C cost. If buyers paid $104 for impressions on which the site received $78, the path's take rate was 25%. If the same bids reach the same buyers through SSP B directly at a lower take rate, every dollar that moves to the direct path pays the publisher more. Buyers win too: they stop seeing a duplicate of the same impression.

    The decision is to remove the RESELLER line and the reseller's adapter. Run the same comparison for every path in the inventory, and model the fee side with the ad tech fee calculator.

    Where floors fit

    Path cuts and price floors interact. Removing a duplicate path can lower bid density, which changes how much a floor costs you in lost fill. Set floors per path after the cuts, not before. The method for first-price auctions is in floor price strategy, and the auction mechanics behind wrappers are in header bidding explained.

    Common mistakes

    1. Judging partners instead of paths. One SSP can be your best direct path and your worst resold one.
    2. Cutting on eCPM alone. A path with a high eCPM and no unique bids adds nothing; a path with a low eCPM and unique buyers may carry a key advertiser.
    3. Ignoring auction duplication. Two routes to the same SSP compete with each other and burn buyer QPS. Pick one route per SSP unless a test proves both pay.
    4. Leaving stale ads.txt lines. An unused RESELLER line is still an authorised path.
    5. Testing without a control group. Before-and-after comparisons confuse a cut with seasonality, news cycles and budget flights.
    6. Forgetting the direct DSP fee. A direct connection still has a price; compare it with the SSP path it replaces, not with zero.
    7. Cutting everything at once. Change one path per test so you know which cut moved revenue.

    FAQ

    What is demand path optimization?
    It is the publisher-side version of supply path optimization. You list every route by which buyers reach your inventory, measure each route's unique bids, fees and data quality, and remove routes that only duplicate others. Buyers already trim paths from their side, so the publisher that prunes first keeps control of which paths survive.
    What is the difference between DPO and SPO?
    SPO is run by buyers, who choose which SSPs and resellers to bid through. DPO is run by publishers, who choose which SSPs, resellers, deals and direct connections to offer. Both use the same ads.txt, sellers.json and SupplyChain data, defined by IAB Tech Lab (ads.txt 1.1).
    How many SSPs should a publisher use?
    There is no correct number. Keep every path whose unique bid share and net revenue justify its latency and fees, and drop the rest after a test. Buyers cap their intake at roughly 1 to 3 million QPS each, according to an Index Exchange estimate, so duplicate paths compete for limited attention (Index Exchange).
    Should I remove resellers from my ads.txt file?
    Remove a reseller when a test shows its bids are duplicated by direct paths. Keep it when it brings buyers you cannot reach directly, such as regional demand. Either way, keep the RESELLER label accurate, because buyers compare it with sellers.json.
    How long should a demand path test run?
    At least two full weeks, so weekdays and weekends both appear in each group. Extend it when budgets change at month or quarter end. Stop early only if a guardrail you set in advance is breached.

    How this works on owned infrastructure

    Demand path optimization depends on one join: which path carried each bid, at what price, and what the publisher was paid. When the wrapper, SSP and ad server belong to different vendors, that join is assembled from exports days later, and unique bid share is often impossible to compute. AdSovereign provides SSP and exchange components designed to run in the publisher's own cloud account or data centre. Every path then writes its bid, win and fee events into one log the publisher controls, so path tests can be read the next morning. The architecture page shows where the event log sits, and the integrations page lists the supported connections.

    Sources

    1. IAB Tech Lab, "ads.txt Specification Version 1.1" (Supply-Chain-Validation repository, accessed 9 November 2026). https://github.com/InteractiveAdvertisingBureau/Supply-Chain-Validation/blob/main/ads.txt%20v1.1.md
    2. IAB Tech Lab, "sellers.json" specification, version 1.0 (Supply-Chain-Validation repository, accessed 9 November 2026). https://github.com/InteractiveAdvertisingBureau/Supply-Chain-Validation/blob/main/sellers-json.md
    3. IAB Tech Lab, "OpenRTB API Specification Version 2.6", Source and SupplyChain objects (accessed 9 November 2026). https://github.com/InteractiveAdvertisingBureau/openrtb2.x/blob/main/2.6.md
    4. AdExchanger, "Attack Of The Clones: Programmatic's Hidden Scourge Of Bid Duplication" (17 January 2024). https://www.adexchanger.com/platforms/attack-of-the-clones-programmatics-hidden-scourge-of-bid-duplication/
    5. PPC Land, "SupplyChain object" (6 September 2026; reports HUMAN Security's diagnostic of 1 November 2023). https://ppc.land/supplychain-object/
    6. Index Exchange, "The Importance of QPS Optimization in Programmatic" (accessed 9 November 2026). https://www.indexexchange.com/index-explains/qps-optimization-programmatic/
    7. PPC Land, "The Trade Desk gains first Dutch publisher for OpenPath at 4.5% fee" (2 July 2026). https://ppc.land/the-trade-desk-gains-first-dutch-publisher-for-openpath-at-4-5-fee/
    8. Fiducia, "ANA Programmatic Transparency Benchmark: Q2 2026 Working-Media Efficiency Reaches a Record 45%" (6 August 2026). https://www.fiducia.eco/post/ana-programmatic-transparency-benchmark-q2-2026-working-media-efficiency-reaches-a-record-45
    9. Prebid.org, "Module: Server-to-Server Testing for Header Bidding" (s2sTesting, accessed 9 November 2026). https://docs.prebid.org/dev-docs/modules/s2sTesting.html