Design de Sistema de Leilão de Anúncios em Escala: Um Deep Dive Completo
![]()
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.
Sumário
- Análise de Requisitos
- Estimativas de Ordem de Grandeza
- Arquitetura de Alto Nível
- Caminho de Serving vs Caminho de Analytics
- Design de APIs
- Formato de Request e Response OpenRTB
- Modelagem de Dados
- Ciclo de Vida de Real-Time Bidding
- Mecânica do Leilão
- Arquitetura do Bidder DSP
- Targeting de Campanhas
- Budget, Pacing e Controle de Gasto
- Frequency Capping
- Ranking e Quality Score
- Feature Store e Model Serving
- Revisão de Creative e Enforcement de Políticas
- Fraude e Tráfego Inválido
- Ingestão de Eventos, Deduplicação e Verdade
- Billing e Reconciliação
- Atribuição de Cliques, Impressões e Conversões
- Privacidade, Consentimento e Minimização de Dados
- Observabilidade e SLOs
- Estratégia Multi-Região e Tail Latency
- Confiabilidade e Degradação
- Dicas para Entrevistas
- Anti-Patterns
- Referências
- Resumo Rápido
Análise de Requisitos
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.
Requisitos Funcionais
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.
Requisitos Não Funcionais
| 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 |
Requisitos de Produto
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.
Fora de Escopo
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.
Perguntas de Clarificação em Entrevistas
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.
Estimativas de Ordem de Grandeza
Números guiam arquitetura. O objetivo não é adivinhar a escala real de uma empresa. O objetivo é revelar gargalos cedo.
Escala Assumida
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.
QPS de Leilão
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.
Carga de Fanout para Bidders
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.
Estimativa de Banda
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.
Estimativa de Ingestão de Eventos
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.
Estimativa de Storage
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.
Budget de Latência
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.
Insight Central
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.
Arquitetura de Alto Nível
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.
flowchart TB
subgraph PublisherSide["Publisher e Supply"]
PUB["Página / App do Publisher"]
SDK["Ad SDK / Tag"]
ADS["Ad Server do Publisher"]
SSP["SSP"]
end
subgraph ExchangeServing["Serving Plane da Exchange"]
EDGE["Edge Regional"]
REQ["Validador de Request"]
ENRICH["Contexto + Consentimento"]
PRE["Pretargeting + Seleção de Bidders"]
FAN["Fanout para Bidders"]
AUCT["Auction Engine"]
RENDER["Builder da Resposta"]
end
subgraph DemandSide["Demand"]
DSP1["DSP Bidder A"]
DSP2["DSP Bidder B"]
DSP3["DSP First-Party"]
end
subgraph DecisionPlane["Decision e Control Plane"]
CAMP["Campaign Service"]
CREATIVE["Creative Review"]
POLICY["Policy Service"]
MODEL["Model Serving"]
FS["Online Feature Store"]
BUDGET["Budget e Pacing"]
FCAP["Frequency Cap Store"]
end
subgraph DataPlane["Data Plane Econômico"]
BUS[("Event Bus")]
DEDUP["Deduplicação"]
BILL["Billing Ledger"]
ATTR["Atribuição"]
FRAUD["Fraud Review"]
REP["Reporting Warehouse"]
end
PUB --> SDK --> ADS --> SSP --> EDGE
EDGE --> REQ --> ENRICH --> PRE --> FAN
FAN --> DSP1
FAN --> DSP2
FAN --> DSP3
DSP1 --> FAN
DSP2 --> FAN
DSP3 --> FAN
FAN --> AUCT --> RENDER --> SSP --> ADS --> SDK
ENRICH --> POLICY
PRE --> CAMP
PRE --> BUDGET
AUCT --> CREATIVE
AUCT --> FCAP
DSP3 --> MODEL
DSP3 --> FS
RENDER --> BUS
AUCT --> BUS
BUS --> DEDUP --> BILL
DEDUP --> ATTR
DEDUP --> FRAUD
DEDUP --> REP
Serviços Principais
| 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 |
Princípio de Design
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.
Caminho de Serving vs Caminho de Analytics
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.
flowchart LR
subgraph Serving["Caminho de Serving"]
REQ["Ad Request"]
SNAP["Snapshots de Serving"]
AUCTION["Leilão"]
RESP["Ad Response"]
end
subgraph Events["Caminho de Eventos"]
LOG["Log Imutável"]
CLEAN["Validação + Dedup"]
FACT["Fatos Billable"]
end
subgraph Finance["Caminho Econômico"]
LEDGER["Billing Ledger"]
INV["Invoices"]
ADJ["Ajustes de Fraude"]
end
subgraph Analytics["Analytics"]
ATTR["Atribuição"]
REPORT["Reporting"]
TRAIN["Training Data"]
end
REQ --> AUCTION --> RESP
SNAP --> AUCTION
AUCTION --> LOG
RESP --> LOG
LOG --> CLEAN --> FACT
FACT --> LEDGER --> INV
FACT --> ADJ --> LEDGER
FACT --> ATTR --> REPORT
FACT --> TRAIN
Regras do Serving Path
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.
Regras do Caminho de Analytics e Billing
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.
Por Que Separar
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.