Lire les logs Prebid.js — ce que le auction log vous dit
Audit pas-à-pas d'un wrapper Prebid.js 9.18 sur publisher news tier-1 FR. Timeouts, win rate par SSP, bid-shading invisible, take-rate ads.txt / sellers.json.
La plupart des post-mortems de yield commencent par regarder le rapport agrégé du SSP. C’est l’inverse de ce qu’il faut faire. Le rapport agrégé est la version commerciale du log. Le log est la version comptable.
Je m’appelle Antoine. Quatre ans chez Criteo côté demande, trois chez Equativ côté supply. En février 2026 j’ai audité un wrapper Prebid.js 9.18 sur un publisher news tier-1 en France — desktop ROS, huit bidders client-side, deux sur Prebid Server S2S, GAM Open Bidding configuré en floor. Le CTO me disait que le yield desktop avait chuté de 19% quarter-over-quarter et que “les SSP underbiddent.” Le log disait autre chose.
Étape 1 — extraire le auction log brut
Sur Prebid.js, le hook pbjs.onEvent('auctionEnd', …) expose tous les bid responses : adapter, CPM, currency, timeToRespond, ad server response. La plupart des publishers le pipent vers BigQuery ou Snowflake via un beacon léger, en gardant 30 à 90 jours rolling. Si le publisher ne logge pas au niveau auction — pas au niveau impression rendue — l’audit s’arrête là. Il faut commencer par instrumenter, et accepter que la première semaine de données ne servira à rien.
Ce qu’on veut sortir du log, par adapter, par GEO, par device, par slot :
bidResponses: combien de bids servis, sur combien d’auctions éligibles.timeToRespond: distribution p50, p95, p99 en ms.noBid: taux et raison (timeout, pas d’inventaire, floor non atteint).winningBid: CPM net après bid shading côté DSP, en € avec deux décimales.
Étape 2 — lire les timeouts contre la latence réelle
Le wrapper du publisher tournait à 800 ms de timeout. Configuration raisonnable sur desktop FR en 2026. Sauf que Magnite répondait à p95 1 140 ms et Index Exchange à p95 920 ms — deux des huit adapters étaient systématiquement droppés de l’enchère avant que leur bid n’arrive. Pas parce qu’ils underbiddaient. Parce que le wrapper les comptait morts à 800 ms et passait à la phase suivante.
Les bids droppés ne génèrent pas de “noBid” dans le rapport SSP. Côté Magnite, l’auction n’a jamais eu lieu. Côté publisher, le slot est rempli — par un bidder plus rapide mais à un CPM inférieur. La perte est invisible sans le log.
Étape 3 — recouper win rate et bid-shading
Sur des first-price auctions, le win rate utile est celui calculé contre les auctions où l’adapter a bid (pas contre toutes les auctions éligibles). Equativ tournait à 28% de win rate sur les auctions où il bid, avec un CPM moyen gagné de 3,80 € net. PubMatic tournait à 31% mais à 2,90 € net. La différence est le bid shading : PubMatic shadait plus agressivement et gagnait plus souvent à un CPM plus bas. Bénéfice pour le publisher : nul.
Sur un sample de 4,2 millions d’auctions desktop ROS, le CPM moyen gagné par Equativ était de 31% supérieur à celui de PubMatic. Le wrapper laissait pourtant PubMatic gagner 53% des auctions où les deux étaient présents, parce que le priceBucket Prebid avec une granularité par défaut de 0,10 € ne distinguait pas suffisamment les bids serrés au seuil. Un passage à customPriceBucket avec granularité 0,01 € sur les CPM au-dessus de 2 € a redonné 4,2 points de win rate à Equativ en deux semaines.
Étape 4 — vérifier sellers.json et le take-rate effectif
Le rapport agrégé du SSP affiche un CPM net. Le log Prebid affiche le CPM gross renvoyé par l’adapter. La différence est le take-rate du SSP, qui n’est jamais documenté dans le wrapper. Sur sellers.json côté Equativ, on lit la chaîne ads.txt → sellers.json et on calcule. Sur ce wrapper, Equativ prenait 12% net. PubMatic prenait 18% net sur l’open exchange et 9% sur les deals PMP directs. Comparer les CPM nets sans normaliser pour le take-rate, c’est comparer deux choses différentes.
Le constat
Trois lignes de config changées dans le wrapper, deux adapters migrés vers Prebid Server S2S pour absorber la latence, granularité du priceBucket affinée. Yield desktop ROS +21% en quatre semaines. Aucun SSP renégocié. Aucune nouvelle demand-source ajoutée. Le rendement était dans le log, pas dans le rapport.
Le auction log de Prebid.js ne ment pas. Le rapport agrégé du SSP, parfois oui — pas par malhonnêteté, mais parce qu’il agrège ce que le SSP voit, jamais ce que le wrapper publisher fait avec ses réponses. La prochaine fois que le yield baisse, ouvrez le log avant d’ouvrir le ticket SSP.
Questions fréquentes
Quels sont les quatre champs minimum à logger dans pbjs.onEvent(‘auctionEnd’) pour que l’audit soit possible ?
Pour chaque adapter, par GEO, device et slot : bidResponses (nombre de bids servis sur les auctions éligibles), timeToRespond en distribution p50, p95 et p99, noBid avec la raison (timeout, pas d’inventaire, floor non atteint), et winningBid en CPM net en euros avec deux décimales. Sans ces quatre champs, l’audit s’arrête à la première étape — il faut instrumenter avant de pouvoir auditer quoi que ce soit.
Pourquoi Magnite et Index Exchange étaient-ils systématiquement droppés sur ce wrapper à 800 ms de timeout ?
Parce que Magnite répondait à p95 à 1 140 ms et Index Exchange à 920 ms — tous deux au-dessus du timeout global de 800 ms. Le wrapper les comptait morts et passait à la phase suivante. Les bids droppés ne génèrent pas de noBid dans le rapport SSP, donc la perte est invisible sans le log. Le slot est rempli par un bidder plus rapide mais à un CPM inférieur. La solution est de migrer ces adapters en Prebid Server S2S, pas de relever le timeout client.
Pourquoi Equativ gagne-t-il à un CPM plus élevé que PubMatic malgré un win rate inférieur ?
PubMatic shade plus agressivement que Equativ sur les first-price auctions. Sur le sample de 4,2 millions d’auctions desktop ROS, le CPM moyen gagné par Equativ était de 31% supérieur à celui de PubMatic. PubMatic gagnait plus d’auctions en proposant des CPM plus bas, mais le publisher-net par auction gagnée était plus faible. L’ajustement par customPriceBucket à 0,01 euro a redonné 4,2 points de win rate à Equativ en deux semaines.
Comment le take-rate effectif d’un SSP diffère-t-il de ce que le rapport agrégé affiche ?
Le rapport SSP affiche un CPM net après fee. Le log Prebid affiche le CPM gross renvoyé par l’adapter. La différence est le take-rate effectif, qui ne figure nulle part dans le wrapper. Sur ce wrapper, Equativ prenait 12% net et PubMatic 18% net sur l’open exchange. Comparer des CPM nets sans normaliser pour le take-rate revient à comparer deux choses différentes — un CPM gross Equativ de 4,15 euros et PubMatic de 3,40 euros ne se comparent qu’après correction du take-rate.
Quels ont été les trois changements de config qui ont généré +21% de yield desktop ROS en quatre semaines ?
Trois lignes de config dans le wrapper, deux adapters migrés en Prebid Server S2S pour absorber leur latence (Magnite et Index Exchange dépassaient le timeout de 800 ms), et la granularité du priceBucket affinée à 0,01 euro sur les CPM au-dessus de 2 euros. Aucun SSP renégocié, aucune nouvelle demand-source ajoutée. Le rendement était dans le log, pas dans le rapport.
Quand le rapport agrégé SSP est-il utile par rapport au log Prebid ?
Le rapport SSP est utile pour les chiffres agrégés mensuels et la facturation. Il est inutile pour l’audit yield parce qu’il agrège ce qui doit être désagrégé — par slot, adapter, GEO, device, viewability — et masque les fuites visibles uniquement dans le log. Règle simple : si la question commence par ‘pourquoi’ (yield en baisse, adapter sous-performant), lire le log. Si la question commence par ‘combien’ au niveau mois et SSP, le rapport agrégé suffit.