Design de Sistema de Leilão de Anúncios em Escala: Um Deep Dive Completo

Software Architect
Pós-graduado em arquitetura de software e soluções. Conecto profundidade técnica com resultados de negócio para entregar produtos que as pessoas realmente usam. Também mentoro desenvolvedores e criadores em programas ao vivo, podcasts e iniciativas de comunidade focadas em tecnologia inclusiva.
Produtos gratuitos e pagos para transformar ideias em uma base que você consegue executar.
13 produtos disponíveisContinue explorando tópicos similares

Um guia prático e senior para desenhar um motor de busca em escala de internet, cobrindo crawler frontier, robots.txt, sitemaps, canonicalização, deduplicação, índice invertido, ranking, snippets.

Um design de sistema de nível produção para editores colaborativos, cobrindo sessões em tempo real, trade-offs entre OT e CRDT, sincronização offline, logs de operações, snapshots, permissões, hist...

A production-grade system design for building recommendation platforms at internet scale, covering candidate generation, retrieval, ranking, feature stores, online inference, real-time feedback loops,
Checklist de 47 pontos para encontrar bugs, riscos de segurança e problemas de performance antes do lançamento.
Templates testados em produção, usados por desenvolvedores. Economize semanas de setup no seu próximo projeto.
Resumo em português: Um design de sistema de nível produção para uma plataforma de real-time bidding parecida com Google Ads e Ad Exchange, cobrindo OpenRTB, exchange serving, DSP bidding, targeting, pacing, ranking, fraude, billing, atribuição, privacidade, observabilidade e trade-offs de entrevista.
Publicado: Fevereiro 2026 Tempo de leitura: 100 minutos Palavras-chave: #SystemDesign #AdAuction #RealTimeBidding #OpenRTB #AdTech #SistemasDistribuidos #Ranking #Pacing #Privacidade #EntrevistaTecnica
Um slot de anúncio aparece em uma página. O navegador ainda está renderizando. O publisher espera receita. O anunciante espera controle. O usuário espera que a página continue rápida e confiável. A exchange tem menos de um segundo para coletar demanda, avaliar lances, aplicar políticas, escolher um vencedor, devolver uma creative, registrar o evento e manter evidências suficientes para cobrança, fraude, relatórios e atribuição. Essa é a tensão central de sistemas de leilão de anúncios. A parte difícil não é apenas "escolher o maior lance". A parte difícil é escolher um anúncio válido sob restrições de latência, orçamento, política, privacidade, qualidade, pacing, frequência, creative e mensuração, enquanto milhões de anunciantes competem por bilhões de oportunidades de impressão. Este artigo desenha um sistema de real-time ad auction parecido em formato com Google Authorized Buyers, Ad Exchange ou uma grande marketplace programática. Ele não descreve a implementação interna do Google. Ele usa conceitos públicos de OpenRTB e Authorized Buyers, depois constrói uma arquitetura defensável em cima deles.
A lição principal: Um leilão de anúncios junta dois sistemas bem diferentes no mesmo domínio de negócio. O primeiro é o caminho de serving. Ele precisa responder em dezenas ou centenas de milissegundos. O segundo é o caminho da verdade econômica. Ele precisa processar impressões, cliques, conversões, invoices, tráfego inválido, ajustes e atribuição com auditabilidade. Se você mistura esses caminhos, o sistema fica lento, frágil e difícil de confiar. Se você separa demais, o leilão passa a decidir com orçamento, caps, fraude e consentimento desatualizados. Design sênior é achar essa fronteira.
Uma plataforma de leilão de anúncios tem pelo menos cinco partes: Publishers ou desenvolvedores de apps com inventário; Supply-side platforms, ou SSPs, que representam esse inventário; Uma exchange que executa o leilão; Demand-side platforms, ou DSPs, que representam anunciantes; Anunciantes que configuram campanhas, budgets, creatives e metas.
A mesma empresa pode operar mais de um papel. Mesmo assim, desenhar essas fronteiras ajuda porque cada papel tem latência, propriedade de dados e falhas diferentes.
A exchange precisa: Receber requests de anúncios de publishers, SDKs, ad servers ou SSPs; Validar inventário, configuração do publisher, consentimento e políticas; Montar bid requests com campos parecidos com OpenRTB; Enviar requests para bidders elegíveis; Aplicar timeout por bidder; Receber bid responses ou no-bid responses; Filtrar lances por creative aprovada, política, blocklists, floor price, deals, seats, consentimento e risco de fraude; Ordenar lances válidos e escolher vencedores; Retornar uma decisão de anúncio renderizável para o publisher; Emitir eventos de auction, win, loss, impressão, clique, conversão, billing e auditoria; Suportar direct deals, private marketplace, open auction e programmatic guaranteed quando fizer sentido; Entregar dados de reporting para publishers, buyers e operações internas.
O DSP precisa: Receber bid requests de uma ou várias exchanges; Decidir se deve dar lance; Escolher campanha e creative elegíveis; Estimar valor usando sinais de targeting, usuário, contexto, campanha e mercado; Aplicar budget, pacing, frequency cap, bid shading e controles de risco; Responder antes do deadline da exchange; Registrar metadados de decisão suficientes para debug e otimização.
O ad server precisa: Decidir quando chamar a exchange; Balancear campanhas diretas, house ads e demanda programática; Aplicar regras do publisher e contratos de rendering; Rastrear delivery, cliques e conversion beacons.
| Requisito | Meta | Por que importa |
|---|---|---|
| Latência interna do leilão | 120ms p99 | Deixa margem para rede, ad server e rendering |
| Deadline de bidder | 80ms a 1000ms conforme formato e tipo de leilão | A documentação pública de Authorized Buyers usa BidRequest.tmax |
| Disponibilidade do serving | 99.99%+ | Ads vazios reduzem receita e confiança do publisher |
| Durabilidade de eventos | sem perda de evento confirmado | Billing e disputa dependem de verdade de eventos |
| Overspend de budget | limitado por reserva explícita de risco | Pacing é aproximado; cobrança não pode depender só de counters |
| Consistência | forte no ledger, bounded-stale no serving | O leilão precisa de velocidade; dinheiro precisa de auditoria |
| Fraude | bloqueio inline só para alta confiança | Falso positivo e falso negativo custam caro |
| Privacidade | consent-aware, minimizada, limitada por propósito | Regras variam por jurisdição e contrato |
A plataforma deve suportar: Display, native, video, mobile app e CTV; Open auction e private marketplace deals; Campanhas CPM, CPC, CPA e value-based; First-price auction por padrão; Bid shading no lado do buyer; Floors, reserves e regras de bloqueio do publisher; Budgets por campanha, line item e conta; Pacing smooth e accelerated; Frequency caps por campanha, anunciante, creative e chave de usuário; Revisão de creative antes do serving; Janelas de atribuição de conversão; Detecção de tráfego inválido e ajustes de cobrança.
Este design não constrói: UI completa de anunciante; Data clean room completo; Motor jurídico de compliance; Implementação de APIs de navegador; Identity graph universal.
Esses sistemas importam. Eles são adjacentes, não o núcleo do design do leilão.
Pergunte cedo: Estamos desenhando a exchange, o DSP ou ambos?; O leilão é first-price, second-price ou híbrido?; Quais formatos de inventário entram no escopo?; Qual é o budget de latência end-to-end?; Budgets são hard real-time ou bounded-risk?; Consentimento chega no bid request?; Precisamos de atribuição de conversão ou só billing por impressão?; Qual caminho é autoritativo para cobrança?.
Para este artigo, assumimos:
Somos donos de uma grande exchange e de um DSP first-party opcional; A exchange usa integração parecida com OpenRTB JSON ou Protobuf; Open auction usa first-price por padrão; Deadlines de bidder vêm de tmax; O p99 interno de serving da exchange mira 120ms; Analytics e billing são event-driven e separados do serving; Todos os números de escala abaixo são assumptions, não métricas públicas.
Números guiam arquitetura. O objetivo não é adivinhar a escala real de uma empresa. O objetivo é revelar gargalos cedo.
Usuários diários alcançados: 600 milhões
Oportunidades de anúncio/dia: 250 bilhões
Multiplicador de pico: 5x
Bid requests por oportunidade: 12 bidders
Tamanho médio de bid response: 2 KB
Tamanho médio de bid request: 6 KB
Lances válidos médios por leilão: 4
Impressões rastreadas/dia: 180 bilhões
Cliques rastreados/dia: 1.8 bilhão
Conversões rastreadas/dia: 120 milhões
Evento normalizado médio: 700 bytes
Writes de frequency cap/dia: 80 bilhões
Esses números são assumptions de design. Em produção, substitua por dados reais do produto.
Oportunidades/segundo média = 250B / 86.400
~= 2,89M oportunidades/s
Oportunidades/segundo pico = 2,89M * 5
~= 14,45M oportunidades/s
Isso é grande demais para um único cluster global. A exchange precisa shardear por região, publisher, tipo de inventário e fonte de tráfego.
Callouts outbound médios/segundo = 2,89M * 12
~= 34,7M callouts/s
Callouts outbound pico/segundo = 14,45M * 12
~= 173,4M callouts/s
Fanout domina custo de rede. A exchange não pode chamar todos os bidders para toda impressão. Ela precisa de pretargeting, quotas, qualidade histórica de resposta, predição de no-bid e traffic shaping.
Banda outbound de bid request no pico:
173,4M callouts/s * 6 KB ~= 1,04 TB/s
Banda inbound de bid response no pico:
173,4M callouts/s * 2 KB ~= 346 GB/s
Mesmo que a escala real seja menor, a direção fica clara: comprimir quando suportado,; colocar bidders perto da região,; manter bid requests compactos,; evitar enrichment desnecessário,; moldar tráfego antes do fanout.
Eventos de impressão/dia: 180B
Eventos de clique/dia: 1.8B
Eventos de conversão/dia: 120M
Eventos de win/loss/debug/dia: 250B+
Eventos rastreados/dia ~= 450B
Média de eventos/s ~= 5,2M
Pico de eventos/s ~= 20,8M
O caminho de eventos precisa ser uma plataforma de streaming. Ele não pode ser um detalhe acoplado ao serviço de leilão.
450B eventos/dia * 700 bytes ~= 315 TB/dia lógico
Com replicação, índices, tabelas derivadas e retention tiers:
arquitetura multi-petabyte/mês é plausível.
Portanto: counters quentes precisam de estado compacto,; logs detalhados precisam de retenção em tiers,; fatos de billing precisam de storage imutável,; traces de debug precisam de sampling,; relatórios agregados precisam de pré-computação.
Assuma que o publisher chama a exchange através de um ad server.
Budget do publisher/ad server: 250ms
Rede até a exchange: 25ms
Pré-processamento da exchange: 10ms
Fanout e espera por bidders: 60ms
Filtros e leilão: 15ms
Montagem da resposta: 5ms
Margem de segurança: 35ms
Isso cria uma meta interna perto de 125ms. Se tmax permitir mais, a exchange pode esperar mais em formatos de alto valor. Se mobile ou CTV tiver latência pior, a exchange precisa reduzir fanout ou usar bidders regionalmente próximos.
Sistemas de leilão de anúncios são limitados por cinco recursos escassos: milissegundos,; capacidade de callout para bidders,; frescor de estado por usuário,; correção de budget,; confiança na verdade dos eventos.
Toda decisão grande de arquitetura gasta ou protege um desses recursos.
Em alto nível, a plataforma tem um serving plane, um decision plane e um data plane econômico. O serving plane responde requests de anúncios. O decision plane gerencia campanhas, modelos, creatives, políticas e configuração de bidders. O data plane econômico registra o que aconteceu e transforma isso em billing, relatórios, fraude e atribuição.
| Serviço | Está no serving path? | Responsabilidade |
|---|---|---|
| Edge Regional | sim | terminar requests perto da supply |
| Request Validator | sim | parsear, autenticar e validar inventário |
| Consent Enrichment | sim | anexar consentimento e modo de privacidade |
| Pretargeting | sim | selecionar bidders elegíveis antes do fanout |
| Bidder Fanout | sim | enviar OpenRTB callouts e aplicar deadlines |
| Auction Engine | sim | filtrar, ranquear, precificar e escolher vencedor |
| Ad Response Builder | sim | devolver markup, tracking URLs ou render token |
| Campaign Service | misto | publicar snapshots compactos para serving |
| Creative Review | não para revisão, sim para cache lookup | aprovar e classificar creatives |
| Budget Service | misto | manter estado de spend e reservas |
| Feature Store | sim para bidder | servir features de baixa latência |
| Model Serving | sim para bidder | estimar CTR, CVR, valor e qualidade |
| Event Bus | não bloqueante direto | transportar eventos duráveis |
| Billing Ledger | não | registros econômicos autoritativos |
| Reporting Warehouse | não | analytics e relatórios |
O auction service não deve chamar sincronicamente warehouse, billing ledger, jobs longos de fraude ou jobs de atribuição. Esses sistemas podem atrasar. O leilão não pode. O leilão pode ler snapshots e counters compactos criados por esses sistemas. Essa é a diferença entre estado de serving e verdade analítica.
A fronteira mais importante é esta: O caminho de serving decide o que mostrar agora. O caminho de analytics prova o que aconteceu depois. Eles compartilham IDs e schemas. Eles não compartilham budgets de latência.
O serving path pode: ler snapshots de política em memória,; ler features online,; ler counters aproximados de spend,; reservar pequenos valores de budget,; escrever eventos em buffers duráveis sem bloquear o fluxo todo,; degradar para menos bidders ou ads de fallback.
O serving path não deve: calcular invoices,; esperar writes de warehouse,; executar joins pesados,; esperar atribuição de conversão,; chamar sistemas terceiros de política inline,; exigir consenso global por impressão.
O caminho de analytics pode: reprocessar eventos,; deduplicar eventos,; corrigir tráfego inválido,; aplicar modelos de atribuição,; gerar relatórios,; produzir fatos billable,; publicar snapshots atualizados para serving.
O caminho de analytics precisa ser auditável. Se um publisher disputa receita ou um anunciante disputa gasto, a plataforma precisa de fatos imutáveis, não só counters que existiam durante o serving.
Sem separação: outages de billing derrubam leilões,; análise de fraude aumenta latência de ads,; backfills de reporting quebram tráfego usuário-facing,; consistência global torna serving regional inviável.
Com separação ruim: budgets estouram,; frequency caps ficam atrasados,; bloqueios de fraude chegam tarde,; anunciantes veem relatórios inconsistentes.
A resposta prática é bounded staleness. O leilão lê estado pequeno, fresco e feito para serving. O data plane calcula verdade durável e republica estado para o serving.
A API externa de serving depende do papel. Integrações de publisher chamam ad tag, endpoint de SDK ou endpoint server-to-server de SSP. Integrações de bidder usam objetos parecidos com OpenRTB. APIs de control plane gerenciam campanhas, creatives, budgets e relatórios.
POST /v1/ad-requests HTTP/1.1
Host: exchange.example.com
Content-Type: application/json
Authorization: Bearer publisher_token
{"request_id":"req_01J9X3R8D7S6Z","publisher_id":"pub_123","site":{"domain":"news.example","page":"https://news.example/world/story","content_categories":["news","international"]},"device":{"ua":"Mozilla/5.0 ...","ip":"203.0.113.10","geo":{"country":"US","region":"CA"}},"user":{"exchange_user_id":"u_opaque_456"},"slots":[{"slot_id":"top_banner","format":"display","sizes":[{"w":970,"h":250},{"w":728,"h":90}],"floor_cpm_micros":2500000}],"privacy":{"consent_string":"opaque","limited_ads":false,"personalization_allowed":true},"timeout_ms":250}
{"request_id":"req_01J9X3R8D7S6Z","ads":[{"slot_id":"top_banner","decision_id":"dec_01J9X3T9A","creative_id":"cr_879","advertiser_domain":"advertiser.example","render_url":"https://cdn.example/render/dec_01J9X3T9A","impression_urls":["https://track.example/imp/dec_01J9X3T9A"],"click_url":"https://track.example/click/dec_01J9X3T9A","expires_at":"2026-02-10T12:00:02Z"}],"debug":{"auction_time_ms":87,"bidder_count":9}}
Em produção, debug precisa ser limitado. Dados de debug podem revelar informações de marketplace.
POST /openrtb2/auction HTTP/1.1
Host: bidder.dsp.example
Content-Type: application/json
A exchange envia um bid request e espera uma bid response antes do deadline. O protocolo pode ser OpenRTB JSON, OpenRTB Protobuf ou uma variação própria. A documentação pública de Authorized Buyers diz que há suporte a OpenRTB Protobuf e JSON.
Criação de campanha não fica no caminho crítico de serving. Ela pode usar APIs transacionais normais.
POST /v1/campaigns
PUT /v1/campaigns/{campaign_id}/budget
POST /v1/creatives
GET /v1/reports/spend
GET /v1/reports/conversions
Writes de control plane precisam de idempotency keys. Requests de serving usam request IDs e event IDs.
Idempotency-Key: camp_create_01J9X5
Para tracking:
impression_id deve ser único por oportunidade renderizada; click_id deve ser único por redirect de clique; conversion_id deve vir do anunciante ou ser gerado pela tag; Deduplicação deve acontecer antes de billing.
Não exponha a verdade de billing pelo mesmo contrato do serving path. Um tracking pixel pode confirmar recebimento rápido. Ele não deve prometer que o evento é billable. Billability só existe após validação, deduplicação, fraude e matching com o log do leilão.
OpenRTB é o vocabulário padrão que muitas exchanges e bidders usam para descrever oportunidades de leilão e respostas de lance. O IAB Tech Lab descreve RTB como uma forma de colocar impressões individuais em leilão programático em tempo real. Guias públicos de Authorized Buyers descrevem um bidder recebendo um bid request, construindo um bid response e respondendo antes do deadline.
{"id":"req_01J9X6","tmax":120,"at":1,"cur":["USD"],"imp":[{"id":"1","banner":{"format":[{"w":300,"h":250},{"w":336,"h":280}]},"bidfloor":1.25,"bidfloorcur":"USD","tagid":"slot_abc"}],"site":{"domain":"publisher.example","page":"https://publisher.example/article"},"device":{"ua":"Mozilla/5.0 ...","ip":"203.0.113.42","geo":{"country":"USA"}},"user":{"id":"opaque_exchange_user_id"},"regs":{"ext":{"gdpr":0}},"user_ext":{"consent":"opaque_consent_string"}}
Campos importantes:
| Campo | Significado |
|---|---|
id | ID único do bid request |
tmax | tempo máximo de resposta em milissegundos |
at | tipo de leilão, comumente first-price para 1 em convenções OpenRTB 2.x |
imp | oportunidades de impressão |
bidfloor | preço mínimo aceito |
site / app | contexto de supply |
device | user agent, IP, device, geo e sinais relacionados |
user | ID de usuário escopado à exchange quando permitido |
regs / extensions | sinais regulatórios e de consentimento |
{"id":"req_01J9X6","seatbid":[{"seat":"buyer_42","bid":[{"id":"bid_abc","impid":"1","price":3.42,"adid":"ad_123","crid":"creative_789","adm":"<div>...</div>","adomain":["advertiser.example"],"w":300,"h":250,"nurl":"https://dsp.example/win/${AUCTION_PRICE}","burl":"https://dsp.example/bill/${AUCTION_PRICE}","lurl":"https://dsp.example/loss"}]}],"cur":"USD"}
Campos importantes de response:
| Campo | Significado |
|---|---|
seatbid | lances agrupados por buyer seat |
impid | impression ID recebido no request |
price | CPM do lance |
crid | identificador da creative |
adm | markup do anúncio ou payload native/video |
adomain | domínio do anunciante |
nurl / burl / lurl | URLs de win, billing e loss quando suportadas |
Um bidder pode decidir não dar lance. Isso não é erro.
No-bid é útil quando: nenhuma campanha combina,; usuário atingiu frequência máxima,; floor está alto demais,; budget não está disponível,; consentimento não permite o uso planejado,; bidder está sobrecarregado.
Documentação pública do Google descreve resposta sem ads e com tempo de processamento, além de mapear no-bid reasons para códigos do OpenRTB.
Mantenha payloads compactos; Use tmax no cálculo de deadline do bidder; Inclua só dados permitidos por consentimento, política e contrato; Trate no-bid como outcome normal; Use creative IDs estáveis e revisáveis; Não dependa de debug string para lógica de produção; Versione extensions com cuidado porque bidders deployam de forma independente.
O modelo de dados tem três camadas:
Não force tudo em um único schema. O modelo de serving otimiza leitura de baixa latência. O modelo de eventos otimiza append e replay. O modelo financeiro otimiza correção e auditoria.
| Entidade | Propósito | Consistência necessária |
|---|---|---|
| Publisher | dono do inventário | forte no control plane |
| InventorySlot | definição do placement | forte no control plane, cache no serving |
| Bidder | endpoint e quota de demand | config forte, cache no serving |
| BuyerSeat | identidade do buyer | config forte |
| Campaign | objetivo e limites do anunciante | config forte, snapshot no serving |
| LineItem | targeting, budget e bid strategy | config forte, snapshot no serving |
| Creative | asset renderizável | review state precisa ser aplicado |
| Deal | termos de marketplace privado | config forte |
| AuctionDecision | vencedor e preço | evento imutável |
| Impression | fato de renderização | evento deduplicado |
| Click | fato de clique | evento deduplicado |
| Conversion | outcome do anunciante | evento deduplicado |
| LedgerEntry | movimento financeiro | forte e imutável |
Serving não deve consultar o banco normalizado de campanhas em todo request. Ele deve ler snapshots compactos.
{"snapshot_version":18422017,"line_item_id":"li_123","campaign_id":"camp_456","advertiser_id":"adv_789","status":"ACTIVE","objective":"MAX_CONVERSIONS","bid_strategy":{"type":"TARGET_CPA","target_cpa_micros":25000000,"max_cpm_micros":8000000},"budget":{"daily_budget_micros":5000000000,"pacing_mode":"SMOOTH","serving_allowed":true},"targeting":{"countries":["US","CA"],"devices":["MOBILE","DESKTOP"],"blocked_publishers":["pub_bad"],"contextual_categories":["sports","finance"]},"frequency_cap":{"max_impressions":3,"window_seconds":86400},"creative_ids":["cr_1","cr_2"]}
O evento de decisão do leilão liga serving e billing. Ele precisa explicar por que um anúncio venceu.
{"event_type":"auction_decision","event_id":"evt_dec_01","request_id":"req_01J9X6","decision_id":"dec_01J9X7","timestamp":"2026-02-10T12:00:00.123Z","publisher_id":"pub_123","slot_id":"top_banner","winning_bid":{"bidder_id":"dsp_a","seat_id":"buyer_42","campaign_id":"camp_456","creative_id":"cr_789","bid_cpm_micros":3420000,"clearing_cpm_micros":3420000,"auction_type":"FIRST_PRICE"},"filter_summary":{"responses":8,"valid_bids":4,"filtered_creative":1,"filtered_floor":2,"timeouts":1},"privacy_mode":"PERSONALIZED_ALLOWED","auction_snapshot_version":18422017}
Billing não deve mutar eventos de leilão. Ele deve criar entradas financeiras derivadas de fatos billable validados.
{"ledger_entry_id":"led_01","billable_event_id":"bill_imp_01","account_id":"buyer_42","counterparty_id":"pub_123","amount_micros":3420,"currency":"USD","entry_type":"AD_SPEND","source":"IMPRESSION","created_at":"2026-02-10T12:01:02Z"}
Para CPM:
custo_da_impressao = clearing_cpm / 1000
Para CPC e CPA, billing depende de validação de clique ou conversão.
| Dado | Store sugerido |
|---|---|
| Control plane de campanhas | banco relacional com audit log |
| Snapshots de serving | KV distribuído / cache em memória |
| Frequency caps | counter store shardeado de baixa latência |
| Reservas de budget | store transacional shardeado ou serviço de counters |
| Logs de auction | event log append-only |
| Fatos billable | lake table imutável mais ledger DB |
| Agregados de reporting | OLAP warehouse |
| Features de modelo | par online/offline feature store |
RTB é um protocolo distribuído curto. Tudo que importa acontece sob deadline.
A exchange recebe contexto: publisher ID,; placement ID,; contexto de página ou app,; contexto de device,; localização coarse quando permitida,; sinais de consentimento e regulação,; identificador de usuário quando permitido,; floor price e metadados de deal.
O validator rejeita requests ruins cedo. Requests inválidos não devem chegar ao fanout.
A exchange enriquece com: quality score do publisher,; classificação do inventário,; categorias bloqueadas,; formatos permitidos,; modo de privacidade,; deals elegíveis,; risco histórico de fraude,; deadline do request.
Esse enrichment precisa usar caches locais ou regionais.
Pretargeting decide quais bidders recebem a oportunidade.
Inputs: quotas de bidder,; formatos suportados,; regiões,; allow/block rules do publisher,; elegibilidade de deals,; probabilidade histórica de no-bid,; score de latência,; bid density esperado.
A exchange não deve fazer fanout para bidders que quase nunca dão lance naquele tráfego.
Fanout precisa aplicar:
deadline absoluto de tmax,; timeout por bidder,; limites de connection pool,; limites de concorrência,; limites de payload,; semântica de resultado parcial.
Bids atrasados são excluídos. A exchange não deve esperar todo bidder se o deadline está acabando.
O leilão filtra: responses malformadas,; bids abaixo do floor,; creatives reprovadas,; domínios de anunciante bloqueados,; tamanho ou formato inválido,; moeda inválida,; deal ID inválido,; ausência de macros exigidas,; violações de política,; violações do modo de privacidade.
Filtros precisam produzir métricas. Filtragem silenciosa torna debug de bidder impossível.
Para first-price auction:
winner = lance válido com maior score efetivo
price = lance vencedor, respeitando floors e regras de deal
Para second-price auction:
winner = maior lance válido
price = max(segundo_maior_lance + incremento, floor)
Muitos leilões programáticos modernos usam dinâmica first-price. Mesmo assim, o sistema precisa de configuração porque deals, integrações legadas e formatos específicos podem mudar a regra.
A resposta inclui: payload da creative ou render URL,; impression tracking URL,; click tracking URL,; expiração,; tamanho selecionado,; metadados seguros para política,; token opcional de debug.
A exchange emite evento de auction imediatamente. A creative renderizada ou SDK emite impressão e clique depois. Billing precisa combinar essas famílias de eventos antes de cobrar.
O auction engine é pequeno em código e enorme em consequência. Ele decide quem acessa atenção. Ele também decide quanto dinheiro se move.
Em first-price auction, o vencedor paga o que ofertou.
Benefícios: pricing mais simples para a exchange,; receita mais clara para o publisher,; menor dependência de mecânica second-price,; comum em header bidding e mercados programáticos modernos.
Custos: bidders precisam de bid shading,; bidders ingênuos pagam caro,; price discovery fica mais difícil,; poder de mercado pode favorecer quem modela melhor.
Em second-price auction, o vencedor paga um preço derivado do segundo melhor lance, sujeito a floors e incrementos.
Benefícios:
Custos:
Maior CPM puro não basta em uma plataforma grande.
A exchange pode ranquear por valor efetivo:
effective_score =
bid_cpm
* creative_quality_multiplier
* predicted_viewability_multiplier
* policy_confidence_multiplier
* publisher_priority_multiplier
Cuidado. Quando a exchange ajusta lances com multiplicadores de qualidade, ela precisa explicar esse comportamento para buyers e publishers. Ajustes ocultos podem parecer manipulação injusta de leilão.
Floors protegem yield do publisher.
Eles podem ser: floor estático por placement,; floor dinâmico por geografia ou device,; floor de deal,; floor por duração de vídeo,; floor por categoria de anunciante,; reserve price gerado por yield optimization.
OpenRTB tem campos de bid floor, e materiais de OpenRTB 2.6 incluem avanços para floors de vídeo e áudio dependentes de duração.
Bid shading é uma estratégia do buyer em first-price auctions. Em vez de ofertar o valor estimado completo, o bidder estima o menor preço que provavelmente vence.
shaded_bid = min(value_estimate, predicted_clearing_price + margin)
Inputs: publisher,; placement,; device,; região,; hora,; formato,; floor,; curvas históricas de win,; competição recente,; tipo de deal.
Shading precisa respeitar metas de campanha. Economizar em impressões que converteriam nem sempre é vitória.
def run_auction(valid_bids, floor_micros, auction_type):
candidates = [b for b in valid_bids if b.price_micros >= floor_micros]
if not candidates:
return None
candidates.sort(key=lambda b: b.effective_score, reverse=True)
winner = candidates[0]
if auction_type == "FIRST_PRICE":
clearing = winner.price_micros
else:
second = candidates[1].price_micros if len(candidates) > 1 else floor_micros
clearing = max(second + 1000, floor_micros)
clearing = min(clearing, winner.price_micros)
return AuctionResult(winner=winner, clearing_price_micros=clearing)
Código real também precisa lidar com: conversão de moeda,; prioridade de deal,; tie-breakers,; pods multi-slot,; separação competitiva,; duração de creative,; regras de qualidade do publisher.
O bidder é onde a estimativa de valor do anunciante acontece. Ele precisa responder rápido e evitar desperdício de budget.
Assuma tmax = 120ms. O bidder não controla todos os 120ms. Rede e overhead da exchange consomem parte.
Rede exchange -> bidder: 10ms
Parsing/privacy gate: 3ms
Campaign matching: 10ms
Budget/frequency checks: 8ms
Feature fetch: 12ms
Model scoring: 15ms
Bid calc + creative: 5ms
Serialização: 2ms
Rede de volta: 10ms
Margem de segurança: 45ms
Sobra pouco espaço para dependências remotas.
O bidder deve preferir: snapshots locais de campanha,; caches locais de feature,; refresh assíncrono limitado,; line items candidatos pré-computados,; modelos compactos,; saídas no-bid cedo.
Matching ingênuo escaneia toda campanha.
Matching de produção usa índices invertidos:
country:US -> line_item_ids
device:MOBILE -> line_item_ids
format:300x250 -> line_item_ids
category:sports -> line_item_ids
publisher:pub_123 -> line_item_ids
O matcher intersecta conjuntos candidatos e depois avalia predicados detalhados. Isso parece retrieval antes de ranking.
Responda no-bid rapidamente quando: consent mode bloqueia o uso planejado,; nenhuma campanha ativa combina,; campanhas candidatas estão sem budget,; usuário está capped,; floor supera o max bid,; creative não está disponível,; bidder está sobrecarregado,; modelo crítico falhou e a política de fallback manda no-bid.
No-bid cedo protege latência e saúde da marketplace.
A exchange deve valorizar comportamento previsível de bidders. Se o bidder dá timeout, a exchange perde tempo escasso. Se o bidder responde no-bid rápido, a exchange usa esse sinal para traffic shaping.
Targeting decide se uma campanha pode dar lance. Ranking decide se ela deve dar lance e por qual preço. Não misture essas ideias.
Dimensões comuns: geografia,; idioma,; device type,; sistema operacional,; navegador ou app,; formato de inventário,; publisher allowlist ou blocklist,; categoria contextual,; content suitability,; hora do dia,; deal ID,; audience segment quando permitido,; lista de remarketing quando permitido,; estado de frequency cap,; consent mode.
Regras hard: campanha ativa,; geografia permitida,; formato suportado,; creative aprovada,; publisher não bloqueado,; consentimento permite o uso pretendido.
Regras soft: CTR previsto,; conversion rate previsto,; valor previsto,; fadiga do usuário,; frescor da creative,; score de exploração.
Regras hard filtram. Regras soft ranqueiam.
Quando personalização por usuário não existe ou não é permitida, o bidder ainda
pode usar sinais contextuais: categoria da página,; categoria de keyword quando fornecida,; categoria do app,; geografia coarse quando permitida,; hora do dia,; device type,; qualidade do publisher,; viewability do placement.
Isso não é bypass de privacidade. É outro modo de targeting com menos dados de usuário.
| Dado | Meta de frescor | Fonte no serving |
|---|---|---|
| Status de campanha | segundos | stream de snapshots |
| Budget gate | subsegundo a segundos | budget service/cache |
| Aprovação de creative | segundos a minutos | creative status cache |
| Taxonomia contextual | horas a dias | classificador de conteúdo |
| Blocklists de fraude | segundos a minutos | snapshot de risco |
| Audience segments | minutos a horas | segment store |
| Frequency caps | quase real time | counter store |
Controle de budget é uma das partes mais difíceis. O leilão precisa gastar de forma suave. O anunciante espera não estourar orçamento. O sistema não pode rodar transações serializáveis globais em toda impressão.
| Budget | Exemplo | Impacto no serving |
|---|---|---|
| Account budget | $1M/mês | guardrail forte da conta |
| Campaign lifetime budget | $100K total | parar depois do spend total |
| Daily budget | $10K/dia | reset ou rollover por timezone |
| Line item budget | $2K/dia | unidade local de otimização |
| Deal commitment | 10M impressões | obrigação de delivery |
O ledger é autoritativo, mas lento demais para todo bid. O bidder usa spend tokens ou reservas regionais. O pacer atualiza tokens com spend recente e curvas de delivery.
Smooth pacing tenta gastar budget ao longo do tempo.
expected_spend_by_now = daily_budget * elapsed_day_fraction
pacing_ratio = actual_spend / expected_spend_by_now
Se pacing_ratio < 1, dê mais lances ou lances maiores. Se pacing_ratio > 1, dê menos lances ou reduza bids.
Uma técnica comum é probabilidade de bid:
bid_probability = clamp(target_spend_rate / eligible_spend_rate, 0, 1)
Se a campanha está adiantada, pule algumas oportunidades elegíveis. Se está atrasada, participe de mais oportunidades.
Para budgets mais rígidos, o bidder reserva budget antes de dar lance.
Fluxo: bidder pede pequeno spend token,; budget service concede se houver budget,; bidder pode dar lance até o valor do token,; win consome token,; loss ou timeout libera token depois do TTL.
Isso reduz overspend, mas adiciona latência e coordenação.
Sistemas grandes costumam usar controles híbridos: tokens regionais aproximados para tráfego normal,; reservas mais rígidas perto do fim do budget,; kill switch quando spend autoritativo cruza limite,; reserva de ajuste para tráfego inválido e eventos tardios.
Overspend acontece porque: impressões chegam depois de wins,; eventos chegam atrasados,; regiões competem,; win notices e render events divergem,; ajustes de tráfego inválido vêm depois,; taxas de câmbio mudam.
Controles: manter buffer de budget,; reduzir tamanho de token perto do limite,; reconciliar com frequência,; parar serving antes do zero exato,; alertar overspend rate,; expor ajustes de billing com clareza.
Não prometa consistência perfeita de budget global em escala de ads sem aceitar sacrifício de latência e disponibilidade. Use overspend limitado, kill switches rápidos, reservas perto do limite e ledger auditável.
Frequency capping limita quantas vezes um usuário vê um anunciante, campanha, line item ou creative dentro de uma janela. Ele protege experiência do usuário e budget do anunciante.
| Escopo | Exemplo |
|---|---|
| Advertiser | máximo 10 impressões/usuário/dia |
| Campaign | máximo 3 impressões/usuário/dia |
| Creative | máximo 1 impressão/usuário/hora |
| CTV pod | não repetir anunciante no mesmo break |
| Deal | máximo N impressões por household quando permitido |
fcap:{scope}:{entity_id}:{user_key}:{window}
Exemplos:
fcap:campaign:camp_123:user_abc:2026-02-10
fcap:creative:cr_777:user_abc:2026-02-10T12
O user_key precisa respeitar privacidade e consent mode. Se uma chave durável de usuário não é permitida, use capping contextual ou de sessão quando apropriado, documentando a menor precisão.
Incrementar no bid é conservador demais. Muitos bids perdem. Incrementar no win é melhor, mas pode contar ads que não renderizaram. Incrementar na impressão é mais limpo para experiência, mas pode atrasar.
Sistemas práticos usam: soft cap em wins recentes,; hard cap em impressões confirmadas,; correção por TTL,; pacing consciente de cap.
Eventos grandes, esportes ao vivo e publishers populares criam hot keys.
Mitigações: shardear counters por hash suffix,; usar sketches aproximados para caps amplos,; cachear negative checks por pouco tempo,; usar counters regionais com reconciliação,; evitar leitura cross-region síncrona.
Ranking em ad auctions não é igual a ranking orgânico. O sistema precisa considerar bid do anunciante, resposta prevista do usuário, qualidade do publisher, política da creative e regras da marketplace.
Um DSP focado em conversões pode estimar:
expected_value_per_impression =
p(click) * p(conversion | click) * conversion_value
Depois converte valor para CPM:
value_cpm = expected_value_per_impression * 1000
Para campanhas CPC:
bid_cpm = max_cpc * predicted_ctr * 1000
Para campanhas CPA:
bid_cpm = target_cpa * predicted_conversion_rate_per_impression * 1000
A exchange pode aplicar regras de qualidade: viewability prevista,; qualidade da landing page,; comportamento de carregamento da creative,; histórico de violações de política,; limites de ad density,; taxa de reclamação de usuários,; risco de malware ou comportamento enganoso.
Controles de qualidade devem ser explícitos e mensuráveis.
Sistemas de ads também precisam de exploração.
Sem exploração: creatives novas nunca coletam dados,; anunciantes novos não competem,; modelos overfitam vencedores antigos,; liquidez da marketplace cai.
Exploração precisa respeitar budget e política. Não explore com creative reprovada ou targeting proibido.
CTR previsto maior pode aumentar receita de curto prazo. Qualidade baixa pode reduzir confiança de publisher e usuário no longo prazo.
O ranking deve otimizar um portfólio: receita imediata do leilão,; outcome do anunciante,; experiência do publisher,; reclamações de usuários,; risco de política,; saúde de longo prazo da marketplace.
O bidder e a exchange precisam de features sob latência apertada. Eles também precisam de dados de treino que representem serving real.
| Categoria | Exemplos |
|---|---|
| Request | formato, tamanho, floor, hora, região |
| Publisher | qualidade do domínio, viewability, CTR histórico |
| User-like | cliques recentes, frequência, segmento quando permitido |
| Campaign | objetivo, bid strategy, budget restante |
| Creative | CTR histórico, review status, load time |
| Mercado | clearing price recente, bid density, win rate |
| Privacidade | consent mode, limited ads mode, finalidades permitidas |
Skew acontece quando: treino usa features indisponíveis no serving,; joins offline vazam informação futura,; defaults online e offline diferem,; filtros de consentimento diferem entre treino e serving,; regras de dedup são diferentes.
Controles: joins point-in-time,; definições compartilhadas de features,; métricas de frescor,; shadow evaluation de modelos,; modelos ou masks específicas por privacy mode.
O bidder deve suportar: fallback rápido com modelo linear ou árvore,; modelo neural mais pesado quando a latência permitir,; cache local de modelo,; tags de versão em metadados de bid,; circuit breakers por modelo,; fallback no-bid para falha crítica.
Feature fetch p99: 10ms
Model inference p99: 15ms
Scoring total p99: 25ms
Se isso estourar, o bidder deve reduzir campanhas candidatas ou trocar para um modelo leve.
Creatives não são só assets. Elas são conteúdo visual e executável entrando em páginas e apps de publishers. Elas podem quebrar layout, enganar usuários, carregar malware, violar regras do publisher ou coletar dados indevidamente.
O guia público de creative da API RTB do Google diz que creatives precisam ser revisadas antes de servir, e que creatives não revisadas ou reprovadas podem ser filtradas. O princípio é geral: não descubra segurança da creative durante o leilão. O leilão deve ler review state de um cache.
declaração de domínio do anunciante,; scan da landing page,; scan de malware,; dimensões da creative,; compatibilidade SSL,; declaração de vendors,; classificação de categoria sensível,; compatibilidade com blocklists de publisher,; duração e formato de vídeo,; requisitos de assets native,; checagens de texto, imagem e política,; comportamento de privacidade e tracking.
creative_id -> {
status: APPROVED,
allowed_formats: ["display"],
advertiser_domain: "advertiser.example",
blocked_publishers: [],
categories: ["IAB3"],
declared_vendors: ["vendor_a"],
last_reviewed_at: "2026-02-10T10:00:00Z"
}
Se o cache está indisponível, o default seguro é filtrar a creative ou usar apenas fallback conhecido como bom.
Política roda em três lugares:
Só a terceira camada é sensível à latência. Não coloque lógica de review manual no serving path.
Fraude protege anunciantes, publishers, usuários e a marketplace. Ela também cria risco perigoso de falso positivo. Um sistema que bloqueia bons publishers destrói supply. Um sistema que deixa bot traffic passar destrói confiança do anunciante.
| Área | Exemplos |
|---|---|
| Impression fraud | ads escondidos, stacked ads, auto-refresh abusivo |
| Click fraud | cliques automatizados, click farms, concorrente clicando |
| Conversion fraud | leads falsos, attribution stuffing |
| Supply fraud | domínios spoofados, inventário não autorizado |
| User fraud | bot traffic, fazendas de emuladores |
| Creative abuse | malware, redirects, cloaking |
Checagens inline precisam ser baratas: IP ou ASN de bot conhecido,; token de publisher inválido,; placement impossível,; domínio ou app bundle bloqueado,; request rate suspeito,; sinais de device malformados,; creative maliciosa conhecida,; sinais de tampering em consentimento.
Inline deve bloquear só abuso de alta confiança. Casos ambíguos devem ser pontuados e revisados depois.
Jobs streaming detectam: picos súbitos de clique,; CTR anormal por placement,; cliques repetidos da mesma chave,; anomalias de tempo entre impressão e clique,; mudança brusca no mix de tráfego do publisher,; bursts de conversão com histórico fraco de clique.
Streaming publica snapshots quentes de risco de volta ao serving.
Jobs batch lidam com: análise de grafos,; detecção de clusters de publishers,; suporte a disputa de anunciante,; fraude de conversão em janela longa,; recomendações de refund e clawback.
Não cobre diretamente de eventos crus. Cobre de fatos billable validados.
Tráfego inválido pode produzir: impressão não billable,; billing atrasado,; crédito ao anunciante,; clawback do publisher,; suspensão de conta,; caso de review manual.
Ingestão de eventos é o sistema nervoso da plataforma. Todo auction decision, impression, click, conversion, win notice, billing notice e model debug passa por ela.
Use IDs diferentes para fatos diferentes:
| ID | Significado |
|---|---|
request_id | request original do leilão |
decision_id | decisão de anúncio selecionada |
impression_id | oportunidade de render/impressão |
click_id | redirect de clique |
conversion_id | evento de conversão do anunciante |
billable_event_id | fato validado cobrável |
Deduplicate por: event ID,; event type,; origem,; janela de tempo,; decision ID,; advertiser event ID para conversões.
Janelas variam: impressões: minutos a horas,; cliques: horas a dias,; conversões: dias a semanas,; fatos billable: idempotência permanente.
Uma impressão billable pode exigir: matching com auction decision,; creative servida dentro da janela de expiração,; publisher e slot compatíveis,; ausência de duplicidade,; ausência de flag de tráfego inválido de alta confiança,; consentimento e política aceitáveis para a finalidade de billing,; requisitos de rendering específicos do formato.
Um clique válido pode exigir: impressão válida anterior,; timestamp de clique após impressão,; clique não duplicado,; clique não gerado por bot conhecido,; redirect chain válida,; domínio de landing compatível com declaração.
Uma conversão válida pode exigir: match com conta do anunciante,; autenticação de tag ou server API,; dedup contra conversion ID do anunciante,; janela de atribuição válida,; consentimento e modo de mensuração compatíveis,; checagens de fraude.
Mantenha: eventos raw imutáveis para replay e auditoria,; eventos normalizados para processamento,; fatos limpos para billing e reporting,; agregados para dashboard rápido.
Nunca sobrescreva eventos raw para "corrigir" histórico. Escreva correções como novos fatos ou adjustment records.
Billing não é o leilão. Billing é a interpretação contábil de eventos validados.
| Modelo | Evento billable | Fórmula |
|---|---|---|
| CPM | impressão válida | clearing_cpm / 1000 |
| CPC | clique válido | clearing_cpc ou bid derivado |
| CPA | conversão válida | preço por action |
| vCPM | impressão viewable | impressão qualificada por viewability |
| Sponsorship | contrato de delivery | termos contratuais |
Para cada cobrança, escreva entradas balanceadas.
Exemplo de impressão CPM:
Debit Advertiser Receivable $0.00342
Credit Publisher Payable $0.00270
Credit Exchange Revenue $0.00072
Os valores por impressão são minúsculos. Isso não torna precisão opcional. Regras de arredondamento precisam ser explícitas e consistentes.
Reconcilie: logs de leilão da exchange,; beacons de impressão,; redirects de clique,; notices de win/billing do DSP,; relatórios do ad server do publisher,; ajustes de fraude,; ledger entries,; invoices e pagamentos.
auction vencido sem impressão,; impressão duplicada,; clique sem impressão válida,; conversão tardia,; DSP reporta clearing price diferente,; creative filtrada depois do bidder achar que venceu,; ad server do publisher contou evento diferente,; ajuste de tráfego inválido aplicado depois do draft da invoice.
A tabela de fatos billable alimenta o ledger. Dashboard pode mostrar spend estimado mais rápido. Invoices precisam usar fatos validados e ajustes.
Atribuição conecta uma interação com anúncio a um outcome. Ela é útil, disputada e fácil de exagerar.
eventos de impressão,; eventos de clique,; eventos de conversão,; metadados de campanha,; chaves user-like quando permitidas,; janelas de tempo,; consentimento e modo de mensuração,; configuração do anunciante.
| Modelo | Descrição | Risco |
|---|---|---|
| Last click | último clique elegível recebe crédito | supervaloriza fundo de funil |
| First click | primeiro clique elegível recebe crédito | supervaloriza descoberta |
| View-through | impressão recebe crédito sem clique | fácil de inflar |
| Linear | crédito dividido entre touches | simples e arbitrário |
| Data-driven | modelo estima contribuição | complexo e menos transparente |
Exemplo:
click-through window: 7 dias
view-through window: 1 dia
conversion dedup window: 30 dias
Essas são assumptions de produto. Anunciantes, jurisdições, browsers e modos de mensuração podem exigir outro comportamento.
Quando ligação por usuário não existe ou não é permitida, use alternativas
mais seguras quando aplicável: reporting agregado,; reporting contextual,; conversões modeladas com caveats claros,; APIs de browser ou plataforma quando disponíveis,; clean rooms para parceiros elegíveis,; nenhuma atribuição quando a base necessária estiver ausente.
Não troque silenciosamente atribuição determinística por modelada. Rotule a métrica.
Privacidade não é um banner na borda. Ela muda quais dados entram no bid request, quais modelos podem usar, quais eventos podem ser ligados e por quanto tempo dados ficam retidos. Este artigo não é aconselhamento jurídico. Sistemas reais precisam de jurídico, políticas e controles por jurisdição. O requisito de engenharia é tornar estado de privacidade explícito e enforceable.
Pergunte para cada campo: É necessário para decisão de auction?; É necessário para prevenção de fraude?; É necessário para billing?; É necessário para reporting?; É permitido para este usuário, publisher, região e parceiro?; Por quanto tempo precisa ser retido?; Pode ser agregado, truncado ou tokenizado?.
A exchange deve montar formatos diferentes de request por privacy mode. Modo personalizado pode incluir IDs ou segmentos permitidos. Modo contextual deve omitir campos de targeting por usuário e usar página, app, formato, contexto coarse e dados do publisher. Modo limited ads pode desativar mensuração personalizada e restringir chamadas de vendors terceiros. O comportamento exato depende de política de produto, contrato e lei aplicável.
As diretrizes do Google Authorized Buyers incluem restrições sobre uso de dados do programa, consentimento, informações sensíveis, segurança, retenção e compartilhamento com vendors. Essas diretrizes não são lei universal. Ainda assim, são um bom exemplo de como uma exchange codifica obrigações contratuais e de privacidade em comportamento de plataforma.
Privacy Sandbox e mudanças em browsers empurram sistemas de ads para menos tracking user-level cross-site e mais APIs preservadoras de privacidade ou estratégias contextuais. Não desenhe um sistema novo assumindo que third-party cookies serão estáveis para sempre.
Desenhe para múltiplos modos de identidade: contexto first-party autenticado,; IDs pseudônimos escopados à exchange quando permitidos,; APIs de browser ou plataforma quando disponíveis,; modo somente contextual,; modo de mensuração agregada,; modo sem anúncios personalizados.
| Dado | Exemplo de retenção |
|---|---|
| Bid requests raw | retenção curta, sampling quando possível |
| Auction decisions | retenção maior para disputas e billing |
| Fatos de impressão/clique | retenção de billing e reporting |
| Features user-level | menor retenção prática |
| Agregados | retenção maior se privacy-safe |
| Ledger entries | requisitos financeiros |
Use retenção por propósito. Não mantenha bidstream para sempre porque "pode ser útil".
Um leilão de anúncios pode falhar retornando HTTP 200. O sistema pode devolver ads que não renderizam, escolher creatives reprovadas, estourar budgets, subentregar campanhas ou gerar invoices incorretas. Observabilidade precisa cobrir comportamento técnico e econômico.
| Área | Métricas |
|---|---|
| Request path | QPS, p50/p95/p99 latency, errors |
| Fanout | bidders chamados, timeouts, no-bid rate, tamanho de response |
| Auction | bid density, valid bid rate, filter reasons, floors |
| Receita | CPM, fill rate, revenue per mille, spend por buyer |
| Delivery | pacing ratio, budget exhaustion, underdelivery |
| Qualidade | creative rejection, policy filters, reclamações |
| Fraude | invalid traffic rate, blocked requests, adjustment amount |
| Billing | lag de billable fact, lag de ledger, reconciliation diffs |
| Privacidade | requests por privacy mode, consent parse failures |
Todo evento deve carregar:
request_id,; auction_id,; decision_id,; publisher_id,; slot_id,; bidder_id quando aplicável,; campaign_id quando aplicável,; creative_id quando aplicável,; privacy_mode,; snapshot_version.
| SLO | Meta |
|---|---|
| Disponibilidade de ad request | 99.99% |
| Latência interna p99 do leilão | < 120ms |
| Timeout rate de fanout | < 2% por bidder-região relevante |
| Lag p99 de auction decision event | < 10s |
| Lag p99 de processamento de impressão | < 60s |
| Lag p95 de geração de billable fact | < 15 minutos |
| Budget overspend rate | < limite de risco acordado |
| Frescor do cache de política de creative | < 5 minutos p99 |
Guias públicos de teste de Authorized Buyers mencionam requisitos de timeout e throttling automático quando timeout rate fica alto. A lição operacional é útil: marketplace pune latência, não só erro.
Alerte em: colapso de fill rate,; colapso de valid bid rate,; spike de filtro de creative,; spike de timeout de bidder,; lag no event bus,; spike de overspend,; falhas de write no ledger,; spike de consent parse failure,; spike suspeito de CTR,; divergência de revenue por região.
Não alerte todo movimento pequeno. Tráfego de ads tem sazonalidade forte. Use baseline por hora, região, classe de publisher e formato.
Ad auctions são sensíveis a geografia. Distância de rede consome budget de leilão. Se a supply está na Califórnia e o bidder só roda na Virgínia, o bidder perde milissegundos antes de executar qualquer lógica.
edge de requests,; auction service,; connection pools para bidders,; snapshots de política,; cache de creative status,; counters quentes de frequência,; buffer local de eventos.
authoring de campanha,; workflow de creative review,; treinamento de modelos,; reporting em warehouse,; billing ledger com ingestão regional,; investigação de fraude.
defina deadlines por bidder abaixo do deadline total,; pare de esperar quando já houver bids suficientes,; evite reads cross-region síncronos,; pré-compute índices de targeting,; mantenha payloads compactos,; use connection reuse com cuidado,; faça shed load com no-bid ou fanout menor,; meça p99 por bidder e região.
Guias de teste de Authorized Buyers observam que receber impressões de várias trading locations normalmente exige bidders em várias regiões.
O princípio geral é simples: Coloque bidders perto do tráfego que eles querem. Não tente vencer física com retries.
O caminho de auction precisa degradar deliberadamente.
Falhas são normais: bidders dão timeout,; feature stores atrasam,; model serving falha,; creative cache tem miss,; budget service fica lento,; event bus particiona,; tráfego de publisher dispara,; snapshots de fraude atrasam.
Use fallback só quando for seguro.
Exemplos: Se cache de creative status está atrasado mas dentro do TTL, sirva apenas creatives aprovadas; Se status da creative é desconhecido, não sirva; Se estado de budget está stale, reduza spend ou no-bid perto do limite; Se consentimento não pode ser parseado, use o modo mais restritivo; Se risk service falhou, bloqueie listas conhecidas e reduza trust para supply arriscada; Se event bus está indisponível, escreva em buffer durável local e faça shed se o buffer encher.
Circuit breakers devem existir para: endpoints de bidder,; model serving,; feature store,; budget service,; creative cache,; produtor do event bus,; integrações de publisher.
Output de circuit breaker deve alimentar traffic shaping. Não continue enviando tráfego valioso para bidder que está dando timeout.
A exchange não deve confirmar eventos econômicos apenas em memória. Use buffers duráveis regionais.
Se buffers encherem: descarte tráfego de baixa prioridade,; reduza fanout,; desative debug logging,; preserve eventos críticos de billing,; alerte imediatamente.
Uma resposta forte não é uma pilha de termos de ad tech. É uma fronteira clara entre decisioning em tempo real e verdade econômica.
Clarifique papel: exchange, DSP ou ad server; Defina assumptions de latência e escala; Desenhe o serving path primeiro; Desenhe o caminho de eventos e billing separado; Explique ciclo OpenRTB de request/response; Adicione targeting, pacing, frequency caps e creative review; Discuta mecânica de leilão e pricing; Adicione fraude, privacidade e observabilidade; Feche com modos de falha e trade-offs.
Diga: "Vou manter o caminho de auction rápido e limitado. Ele lê snapshots, counters e caches de política. Ele emite eventos imutáveis. Billing e atribuição rodam assincronamente a partir de fatos deduplicados. Budget e frequência voltam para o serving via counters de baixa latência com bounded staleness." Essa frase mostra separação de nível sênior.
| Tema | Trade-off |
|---|---|
| Fanout | mais demanda vs mais latência e banda |
| Budget consistency | counters globais exatos vs serving regional rápido |
| Fraude | bloqueio inline vs falso positivo |
| Privacidade | yield de personalização vs minimização de dados |
| Bid shading | eficiência do buyer vs risco de win-rate |
| Floors dinâmicos | yield do publisher vs confiança do buyer |
| Frequency capping | experiência do usuário vs custo de counters |
| Atribuição | utilidade vs incerteza e privacidade |
Como evitar budget overspend?; Como lidar com bidder timeout?; Como detectar click fraud?; Como deduplicar impressões?; Como aplicar aprovação de creative?; Como lidar com ausência de consentimento?; Como calcular clearing price?; Como debugar por que um bidder perdeu?; Como escalar frequency caps?; Como reconciliar invoices?.
Budget: Use pacing tokens, counters regionais, reservas mais rígidas perto do limite e reconciliação autoritativa no ledger.
Timeouts:
Use tmax, deadlines por bidder, circuit breakers, posicionamento regional e traffic shaping.
Fraude: Bloqueie abuso de alta confiança inline, pontue casos cinzentos em streaming, revise padrões longos em batch e ajuste billing via ledger entries.
Privacidade: Propague privacy mode para construção de bid request, seleção de features, logging, atribuição, retenção e controles de vendors.
Isso desperdiça banda e latência. Use pretargeting, quotas, relevância de bidder, no-bid prediction histórica e suporte a formato.
No-bid é uma resposta normal de marketplace. Meça no-bid reasons e use para otimização.
Eventos crus podem ser duplicados, forjados, tardios ou inválidos. Cobre a partir de fatos validados e casados com auction decisions.
Isso quebra latência e disponibilidade. Use estado bounded-stale no serving e reconciliação financeira forte.
Review precisa acontecer antes do serving. O leilão só deve checar caches rápidos de aprovação e política.
Quality multipliers opacos, floors dinâmicos e fees escondidas destroem confiança de marketplace. Deixe pricing e filtros explicáveis para parceiros.
Latência média é irrelevante quando bids atrasados são excluídos. Meça p99 por bidder, região, formato e publisher.
Features disponíveis mudam com consentimento e contexto. Use feature masks, modelos por modo ou fallbacks seguros.
Atribuição é uma regra ou modelo, não a realidade em si. Separe métricas determinísticas, modeladas, click-through e view-through.
Publishers se importam com qualidade do anúncio, categorias, separação competitiva, performance da página e confiança do usuário. Maior bid nem sempre é demanda aceitável.
Referências primárias usadas neste design:
Conceitos úteis para revisar depois:
tmax em bid requests e testes de timeout.Ad request
-> validar inventário e consentimento
-> enriquecer contexto
-> selecionar bidders
-> enviar OpenRTB requests
-> coletar responses até o deadline
-> filtrar bids
-> executar leilão
-> retornar creative/render token
-> emitir evento de auction
Auction decision
+ eventos de impressão/clique/conversão
-> normalizar
-> deduplicar
-> validar
-> checar fraude
-> fatos billable
-> ledger
-> invoices e payouts
| Store | Propósito |
|---|---|
| Campaign DB | source of truth de configuração |
| Serving snapshot cache | leituras rápidas de campanha e política |
| Frequency cap store | counters por usuário-like |
| Budget service | spend tokens e pacing state |
| Feature store | features online para modelos |
| Event log | stream imutável de eventos |
| Ledger | verdade financeira |
| Warehouse | analytics e reporting |
Use tmax como deadline forte; Bid atrasado perde; No-bid não é erro; Filtre antes de ranquear; Aplique aprovação de creative antes de servir; Respeite floors e deal rules; Mantenha pricing explicável; Logue o suficiente para debugar toda decisão.
Ledger é autoritativo; Serving usa estado bounded-stale; Smooth pacing usa curvas de spend; Accelerated pacing recupera atraso; Reservas reduzem overspend perto do limite; Tokens regionais evitam hot counters globais; Alertas detectam drift de budget.
Parseie consentimento antes de montar bid requests; Inclua apenas campos permitidos; Use fallback contextual quando personalização não estiver disponível; Propague privacy mode para logs e atribuição; Retenha dados user-level só pelo tempo necessário ao propósito declarado; Evite claims jurídicas absolutas em docs de engenharia.
Se você tiver dez minutos:
Desenhe o serving path da exchange; Desenhe event/billing path separado; Explique fanout OpenRTB e tmax; Explique first-price auction com floors; Adicione matching de campanha, pacing e frequency caps; Adicione creative review e filtros de fraude; Explique fatos billable deduplicados e ledger; Discuta privacy modes e fallback contextual; Feche com tail latency, placement regional e degradação.
Um sistema de leilão de anúncios é um mercado de baixa latência no front e um sistema financeiro auditável no back. O front pode ser aproximado, cacheado e regional. O back precisa ser durável, reprocessável e correto. A arquitetura funciona quando esses dois sistemas trocam estado compacto e eventos imutáveis sem fingir que têm o mesmo trabalho.