Projetando Sistemas de Recomendação em Escala: Guia Completo de System Design

Resumo em português: Um guia de nível produção para construir plataformas de recomendação em escala de internet, cobrindo geração de candidatos, retrieval, ranking, feature store, inferência online, loops de feedback em tempo real, experimentação, confiabilidade e trade-offs de entrevista.

Publicado: Fevereiro 2026

Tempo de leitura: 100 minutos

Palavras-chave: #SystemDesign #RecommendationSystem #Ranking #Retrieval #FeatureStore #MLSistemas #SistemasDistribuídos #Escalabilidade #EntrevistaTécnica

Um usuário abre o app por 15 segundos enquanto espera um café. Nesse intervalo, o sistema precisa decidir:

  • quais itens aparecem no topo,
  • quais criadores entram no feed,
  • quais produtos vão para a vitrine,
  • quanto de exploração vale a pena antes de prejudicar a experiência.

Um erro isolado quase não muda nada.

Um milhão de erros por minuto muda retenção, receita, distribuição de exposição e confiança no produto.

Esse é o ponto central: recomendação não é só "treinar um modelo". É um problema de arquitetura distribuída com componentes de ML, contratos de latência e operação em produção.

Em entrevistas, respostas medianas param em "vamos usar collaborative filtering". Respostas senior mostram pipeline completo, limites de latência por etapa, consistência de features, degradação controlada e governança de modelo.

Este guia segue esse nível.

Sumário

  • Análise de Requisitos
  • Cálculos de Envelope
  • Arquitetura de Alto Nível
  • Design de API
  • Modelagem de Dados
  • Pipeline de Geração de Candidatos (Core 1)
  • Retrieval e Infra de ANN (Core 2)
  • Ranking e Re-Ranking (Core 3)
  • Arquitetura de Feature Store (Core 4)
  • Ingestão de Sinais em Tempo Real (Core 5)
  • Exploração, Diversidade e Restrições (Core 6)
  • Feedback Loops e Governança de Modelos (Core 7)
  • Confiabilidade de Serving e Fallbacks (Core 8)
  • Treinamento, Validação e Deploy
  • Experimentação e Medição Causal
  • Caching e Sharding
  • Multi-Região e Disaster Recovery
  • Segurança, Privacidade e IA Responsável
  • Observabilidade e SLOs
  • Dicas para Entrevista
  • Anti-Patterns para Evitar
  • Conclusão
  • Referências
  • Referência Rápida

Análise de Requisitos

A primeira decisão é delimitar o problema. "Sistema de recomendação" pode significar feed social, ecommerce, vídeo curto, trilhas de aprendizado, ranking de vagas, anúncios ou busca personalizada.

Sem escopo, tudo vira abstrato e a arquitetura perde precisão.

Requisitos Funcionais

  1. Gerar candidatos personalizados para cada usuário.
  2. Ranquear candidatos por utilidade prevista, respeitando restrições.
  3. Responder em latência baixa e previsível.
  4. Atualizar recomendações conforme novas interações.
  5. Tratar cold-start de usuários e itens.
  6. Ter fallback quando componentes de ML falharem.
  7. Expor metadados mínimos de explicação quando necessário.
  8. Suportar A/B tests, canary e rollback seguro.

Requisitos Não-Funcionais

Requisito

Meta

Motivo

Latência API recomendação

< 120ms p99

UX fluida e retenção

Disponibilidade

99,99%

Superfícies centrais dependem disso

Freshness de sinais

segundos a poucos minutos

personalização desatualizada perde valor

Escala

milhões de req/s em picos

plataformas globais

Consistência

eventual para features, forte para configuração

equilíbrio entre custo e controle

Degradação

sem tela vazia em falhas de ML

resiliência de produto

Métricas de Sucesso

Você não otimiza só CTR. Um sistema maduro monitora cesta de métricas:

  1. CTR
  2. dwell/watch time
  3. conversão
  4. profundidade de sessão
  5. retenção D1/D7/D30
  6. distribuição de exposição por creator/seller
  7. métrica de qualidade e diversidade
  8. latência e erro de serving

Perguntas de Clarificação (Entrevista)

  1. Qual superfície vamos otimizar primeiro (home feed, discover, produto)?
  2. Qual o budget de latência por request?
  3. Quão rápido um clique precisa impactar ranking?
  4. Existe requisito formal de fairness/diversidade?
  5. Qual é o tamanho do catálogo ativo?

Premissas para Este Guia

  • Superfícies tipo feed e discover.
  • p99 fim-a-fim <= 120ms.
  • Personalização quase em tempo real.
  • Experimentação obrigatória.
  • Fallback obrigatório.

Cálculos de Envelope

Aqui o objetivo não é acertar número exato. É mostrar maturidade para guiar escolhas de arquitetura.

Hipóteses de Escala

DAU: 400 milhõesRequests de recomendação/dia: 120 bilhõesItens retornados por request: 20Pool inicial de candidatos por request: 2.000Catálogo ativo: 1,5 bilhão de itensEventos de interação/dia: 2,8 trilhõesPico: 5x média

QPS de Serving

QPS medio = 120.000.000.000 / 86.400 ~= 1.388.889QPS de pico (5x) ~= 6.944.445

Custo de Scoring Sem Multi-Estágio

Se você tentar pontuar 2.000 candidatos com modelo pesado em todo request:

6,94M req/s * 2.000 candidatos ~= 13,9 bilhões de scores/s

Isso é caro demais e tende a explodir latência/custo.

Por isso o padrão industrial é:

  1. retrieval barato em lote grande,
  2. ranking pesado em lote menor,
  3. reranking final no top curto.

Ingestão de Eventos

2,8 trilhões/dia ~= 32,4M eventos/s (média)Pico (3x) ~= 97M eventos/s

Exige streaming particionado, schema governance e controles de qualidade.

Armazenamento (direcional)

Assumindo 200 bytes por evento comprimido:

2,8T * 200B ~= 560TB/dia lógico

Conclusão: retenção precisa de políticas por camada (hot, warm, cold) e sampling inteligente.

Insight Principal

Os gargalos reais são:

  1. eficiência retrieval + ranking,
  2. freshness de features,
  3. paridade treino-serving,
  4. proteção contra regressão de qualidade.

Arquitetura de Alto Nível

flowchart TB subgraph Clientes APP["Mobile/Web"] end subgraph Serving API["Recommendation API"] ORQ["Orchestrator"] RET["Retrieval Service"] RANK["Ranking Service"] RER["Re-ranker + Constraints"] FALL["Fallback Service"] end subgraph Online Data OFS["Online Feature Store"] UEMB["User Embedding Store"] IANN["ANN Item Index"] PROF["Profile Store"] CACHE[("Redis")] end subgraph Data & Training EVT["Event Collector"] BUS[("Kafka/PubSub")] FPIPE["Feature Pipelines"] OFFS["Offline Feature Store"] TRAIN["Training Pipeline"] REG["Model Registry"] DEP["Model Deploy"] DWH[("Warehouse")] end APP --> API --> ORQ ORQ --> RET --> IANN ORQ --> OFS ORQ --> RANK RANK --> RER RER --> ORQ ORQ --> FALL ORQ --> CACHE EVT --> BUS BUS --> FPIPE --> OFS FPIPE --> OFFS OFFS --> TRAIN --> REG --> DEP --> RANK BUS --> DWH TRAIN --> UEMB TRAIN --> IANN

Princípios Arquiteturais

  1. Multi-estágio para controlar custo de inferência.
  2. Separação clara entre plano online e plano offline.
  3. Contratos versionados de features e modelos.
  4. Fallback como funcionalidade de produto, não gambiarra.
  5. Observabilidade de sistema e de modelo lado a lado.

Design de API

API boa para recomendação precisa carregar contexto e restrições, sem estourar payload.

Endpoint Principal

POST /v1/recommendations

Request:

{ "request_id": "req_2381", "user_id": "u_991", "surface": "HOME_FEED", "context": { "device": "ios", "locale": "pt-BR", "timezone": "America/Sao_Paulo", "network_type": "wifi" }, "session": { "session_id": "s_882", "entry_point": "app_open" }, "constraints": { "max_items": 20, "allow_sensitive": false, "diversity_level": "medium" }, "debug": false}

Response:

{ "request_id": "req_2381", "model_version": "ranker_v278", "items": [ { "item_id": "i_101", "score": 0.9281, "reason_codes": ["similar_interest", "fresh_content"], "rank": 1 } ], "served_at": "2026-02-22T23:40:10Z", "fallback_used": false, "trace_id": "tr_5502"}

Endpoint de Eventos

POST /v1/recommendations/events

{ "event_id": "evt_901", "request_id": "req_2381", "user_id": "u_991", "item_id": "i_101", "event_type": "CLICK", "position": 1, "surface": "HOME_FEED", "event_ts": "2026-02-22T23:40:21Z"}

Dedupe de Evento

dedupe_key = event_idoudedupe_key = (request_id, user_id, item_id, event_type, bucket_ts)

Sem dedupe, você duplica feedback positivo/negativo e distorce treino.

Modelagem de Dados

Recomendação mistura formatos diferentes:

  • eventos append-only,
  • features online mutáveis,
  • snapshots históricos para treino,
  • configurações de experimento e rollout.

Objetos Principais

  1. UserFeatures
  2. ItemFeatures
  3. InteractionEvent
  4. ModelArtifact
  5. DeploymentConfig
  6. ExperimentAssignment

Exemplo de Feature de Usuário

{ "user_id": "u_991", "embedding": [0.12, -0.44, 0.89], "recent_topics": ["ml", "system-design", "cloud"], "activity_1d": { "views": 52, "clicks": 13, "likes": 2 }, "quality_signals": { "session_depth_avg_7d": 8.2, "negative_feedback_ratio": 0.07 }, "updated_at": "2026-02-22T23:31:01Z"}

Exemplo de Feature de Item

{ "item_id": "i_101", "creator_id": "c_55", "embedding": [0.02, 0.88, -0.31], "tags": ["distributed-systems", "architecture"], "freshness_hours": 3, "quality_score": 0.82, "policy": { "eligible_surfaces": ["HOME_FEED", "DISCOVER"], "sensitivity_level": "LOW" }, "updated_at": "2026-02-22T23:29:44Z"}

Tabela de Assignment de Experimento

CREATE TABLE experiment_assignments ( experiment_id VARCHAR(64) NOT NULL, user_id BIGINT NOT NULL, variant VARCHAR(32) NOT NULL, assigned_at TIMESTAMP NOT NULL, PRIMARY KEY (experiment_id, user_id));

Diagrama ER Simplificado

erDiagram USER ||--o{ INTERACTION_EVENT : emits ITEM ||--o{ INTERACTION_EVENT : receives USER ||--|| USER_FEATURES : has ITEM ||--|| ITEM_FEATURES : has MODEL ||--o{ MODEL_DEPLOYMENT : deployed_as EXPERIMENT ||--o{ EXPERIMENT_ASSIGNMENT : assigns USER ||--o{ EXPERIMENT_ASSIGNMENT : belongs_to

Pipeline de Geração de Candidatos (Core 1)

Você nunca rankeia catálogo inteiro. Primeiro você reduz espaço de busca.

Fontes de Candidatos

  1. Collaborative filtering.
  2. Similaridade por embedding.
  3. Popularidade/trending por contexto.
  4. Afinidade social (follows, grafo).
  5. Candidatos estratégicos de negócio (com limites).

Blend de Candidatos

final_candidates = unique( topK(collab, 500) U topK(embedding, 600) U topK(trending, 200) U topK(business, 100))

Sequência de Candidatos

sequenceDiagram participant O as Orchestrator participant CF as CF Generator participant ANN as Embedding Retriever participant POP as Trending Generator participant BIZ as Business Generator participant M as Candidate Merger O->>CF: get candidates(user) O->>ANN: get nearest neighbors O->>POP: get contextual popular O->>BIZ: get business candidates CF-->>M: set A ANN-->>M: set B POP-->>M: set C BIZ-->>M: set D M-->>O: merged dedup candidates

Cold-Start

Usuário novo

  • popularidade por contexto (cidade/idioma/horário),
  • sinal de onboarding,
  • exploração maior no início.

Item novo

  • embeddings por conteúdo/metadado,
  • exploração controlada,
  • limites por confiança de qualidade.

Retrieval e Infra de ANN (Core 2)

ANN costuma ser a etapa mais sensível em latência e infra.

Requisitos do Index

  1. Alta recall com latência baixa.
  2. Atualizações incrementais.
  3. Particionamento por vertical/locale quando necessário.
  4. Escalabilidade para bilhões de vetores.

Caminho de Retrieval

  1. Buscar embedding do usuário.
  2. Consultar ANN para top-N próximos.
  3. Aplicar filtros grossos (policy, idioma, elegibilidade).
  4. Retornar ids para o ranker.

Diagrama de Retrieval

flowchart LR U["User Embedding"] --> A["ANN Cluster"] A --> N["Nearest Candidates"] N --> F["Coarse Filters"] F --> O["Output Candidates"]

Estratégias de Refresh do Index

Estratégia

Vantagem

Desvantagem

Uso

rebuild diário

simples

staleness alta

superfícies menos sensíveis

incremental horário

bom equilíbrio

mais complexidade

padrão

quase realtime

freshness máxima

custo alto

superfícies premium

Budget de Latência (exemplo)

Budget total: 120ms- API + orchestration: 15ms- retrieval: 30ms- fetch de features: 25ms- ranking + reranking: 35ms- serialização/rede: 15ms

Ranking e Re-Ranking (Core 3)

Essa é a etapa de maior impacto na qualidade percebida.

Padrão Multi-Estágio

  1. Pre-ranker leve em ~2.000 candidatos.
  2. Ranker mais pesado em ~300.
  3. Re-ranker em ~50 para restrições finais.

Features Comuns

  • Usuário: afinidade, recência, profundidade de sessão.
  • Item: qualidade, freshness, risco de policy.
  • Contexto: dispositivo, rede, horário.
  • Cruzadas: histórico usuário-item, similaridade semântica.

Input do Ranking Service

{ "user_id": "u_991", "surface": "HOME_FEED", "candidate_ids": ["i_101", "i_102"], "feature_refs": { "online_snapshot_id": "ofs_788" }, "model_version": "ranker_v278"}

Re-Ranking com Restrições

flowchart TB I["Ranked List"] --> D["Diversity Layer"] D --> P["Policy Filter"] P --> B["Business Constraints"] B --> F["Final List"]

Restrições Típicas

  1. Cota máxima por creator.
  2. Diversidade mínima por tópico/fonte.
  3. Bloqueios de policy.
  4. Posições reservadas com limite estrito.
  5. Quota de freshness.

Erro Comum

Otimizar CTR imediato sem guardrails de longo prazo piora ecossistema e retenção.

Arquitetura de Feature Store (Core 4)

A maior causa de regressão silenciosa em ML de recomendação é mismatch treino-serving.

Objetivos

  1. Baixa latência online.
  2. Histórico offline confiável.
  3. Definições únicas e versionadas de features.
  4. Point-in-time correctness no treino.

Fluxo de Features

flowchart LR E["Raw Events"] --> T["Transforms"] T --> OFF["Offline FS"] T --> ON["Online FS"] OFF --> TR["Training"] ON --> INF["Online Inference"]

Exemplo de Definição Versionada

feature_name: user_click_rate_7dentity: user_idlogic: clicks_7d / impressions_7dsource: interaction_eventsupdate_mode: streamingonline_ttl: 10moffline_backfill: dailyversion: v91

Point-in-Time (regra)

No treino, joins só podem usar dados disponíveis até o timestamp do label.

Qualquer "vazamento de futuro" infla métrica offline e quebra em produção.

Boas Práticas

  1. Registry central de features.
  2. Tests de consistência online/offline.
  3. Monitoramento de null-rate e drift por feature.
  4. Rollback rápido de feature version.

Ingestão de Sinais em Tempo Real (Core 5)

Sem eventos frescos, personalização degrada rápido.

Eventos Mais Importantes

  1. Impression
  2. Click
  3. Like/Favorite
  4. Share
  5. Add-to-cart
  6. Purchase
  7. Hide/Not interested
  8. Session end

Pipeline de Eventos

flowchart TB SDK["Client SDK"] --> COL["Event Collector"] COL --> BUS["Kafka/PubSub"] BUS --> VAL["Schema Validators"] VAL --> RT["Realtime Feature Jobs"] RT --> OFS["Online FS"] BUS --> DWH["Warehouse"]

Controles de Qualidade de Dados

  1. Schema registry e compatibilidade.
  2. Dedupe de eventos.
  3. Tratamento de clock skew.
  4. Watermarks para atraso.
  5. Filtragem de bots e fraude.

Freshness SLA

Sinais de alta relevância devem impactar serving em segundos, não horas.

Exploração, Diversidade e Restrições (Core 6)

Sem exploração, o sistema converge para repetição e perde descoberta.

Estratégias de Exploração

  1. Epsilon-greedy por segmento.
  2. Thompson sampling.
  3. Contextual bandits.
  4. Buckets de exploração controlada por superfície.

Restrições de Diversidade

  1. Diversidade de fonte.
  2. Diversidade de tópico.
  3. Controle de repetição por creator.
  4. Quota mínima de itens novos.

Objetivo com Restrições

max expected_utility(items)subject to:- policy_eligible(item)- creator_repeat_cap <= threshold- min_diversity_score >= threshold- sponsored_slots <= limit

Trade-off

Política

Pro

Contra

sem exploração

estabilidade de curto prazo

estagnação e viés de exposição

exploração agressiva

aprendizado rápido

queda de métrica imediata

exploração controlada

equilíbrio

exige disciplina de experimento

Dica Prática

Comece simples:

  1. ranker determinístico,
  2. exploração pequena e observável,
  3. guardrails fortes,
  4. evolução gradual.

Feedback Loops e Governança de Modelos (Core 7)

Seu modelo altera o próprio dado que vai treinar o próximo modelo.

Riscos Clássicos

  1. Rich-get-richer de creators já grandes.
  2. Redução extrema de cobertura de catálogo.
  3. Bolhas de tópicos.
  4. Viés histórico auto-reforçado.

Controles de Governança

  1. Monitorar distribuição de exposição.
  2. Definir limites de concentração.
  3. Medir coortes sensíveis separadamente.
  4. Incluir objetivos de longo prazo.
  5. Manter rollback rápido por degradação.

Metadados de Registro de Modelo

{ "model_name": "ranker_v278", "training_data_window": "2026-01-20..2026-02-18", "feature_set_version": "fs_v91", "offline_metrics": { "auc": 0.812, "ndcg_20": 0.442, "coverage_1k": 0.71 }, "guardrails": { "creator_gini_max": 0.82, "latency_p99_ms_max": 40 }}

Regra de Promoção

Modelo novo só sobe se:

  1. melhorou métrica primária,
  2. respeitou guardrails,
  3. passou canary sem regressão operacional.

Confiabilidade de Serving e Fallbacks (Core 8)

Falha de recomendação não pode virar tela vazia.

Hierarquia de Fallback

  1. Personalizado principal.
  2. Cache curto por usuário.
  3. Lista contextual (popular por locale/superfície).
  4. Lista global segura.

Fluxo com Degradação

sequenceDiagram participant App as Cliente participant API as Rec API participant RET as Retrieval participant RANK as Ranking participant F as Fallback App->>API: get recommendations API->>RET: retrieve candidates alt stack principal saudável RET-->>API: candidates API->>RANK: score RANK-->>API: ranked API-->>App: personalized list else degradado API->>F: fallback(context) F-->>API: fallback list API-->>App: fallback list end

Circuit Breakers Importantes

  1. Timeout em ANN.
  2. Timeout em inferência de ranker.
  3. Limite de dependência por request.
  4. Queda para degradado em caso de erro repetido.

Regra de Produto

Retornar lista não-vazia sempre que policy permitir.

Treinamento, Validação e Deploy

Sem disciplina aqui, modelo bom no notebook vira incidente em produção.

Pipeline de Treino

Source

1 share