Chega de acoplar um data warehouse: incorpore DuckDB 2.0 para analytics em tempo real

Por Diogo Hudson Dias
Engineers reviewing a cloud cost dashboard next to a local analytics process running on a workstation with charts and system metrics.

Você está pagando preço de data warehouse para renderizar 12 cards em um dashboard do cliente. Cada clique se espalha para um serviço na nuvem que cobra por consulta, por segundo e por byte lido. A latência é imprevisível. A fatura, não. Com o DuckDB 2.0 no horizonte (o preview já está circulando), é hora de inverter o padrão: coloque o OLAP no seu app, não em um data warehouse distante.

O motor colunar embutido do DuckDB vem sendo o segredo mais mal guardado de dados há anos. O que muda agora é a maturidade. O ciclo 2.0 sinaliza uma base estável, I/O mais rápido e uma história mais clara para extensões e tratamento de resultados grandes. Você não precisa esperar o selo GA para começar a pilotar: a arquitetura e os trade-offs são bem compreendidos. E, para uma grande classe de dashboards de SaaS, analytics dentro do produto e explorações ad hoc, o OLAP incorporado vence os serviços de consulta serverless em custo, latência, privacidade e simplicidade.

O que dá errado quando você “acopla um data warehouse”

Data warehouses e mecanismos de consulta serverless são brilhantes para analytics multi-tenant e entre domínios. Eles são ruins para alimentar interações de produto em tempo real. Você sente isso em três frentes:

  • Economia unitária sem limites. Se você empurra 100k carregamentos de dashboard/dia a US$ 5 por 1.000 consultas, isso dá ~US$ 15k/mês em taxas de consulta antes de storage, egress ou “aceleradores”. Isso cresce junto com o produto porque o cache otimizado é problema de outra pessoa.
  • Latência de UI que você não controla. Mesmo warehouses rápidos oscilam. Um “simples” group-by sobre alguns GB pode dar 200ms na segunda-feira, 1,5s na sexta, e o custo de aparar essa variação cai em você.
  • A gravidade dos dados trabalha contra você. Exportar tabelas de features, logs de eventos ou snapshots por tenant para um warehouse adiciona pipelines, backfills e modos de falha. Auditorias e residência de dados multiplicam a sobrecarga.

Quando a pergunta é “mostrar a este cliente os últimos 90 dias de uso com 5 filtros”, você não precisa de uma rede de leaf nodes em escala de internet. Você precisa de varreduras colunares rápidas in-process com controle apertado de CPU, cache e memória.

Onde o DuckDB 2.0 muda o padrão

DuckDB é um engine SQL colunar e vetorizado que você pode embutir no seu app (C/C++, Python, Node, Rust, Go, Java) e apontar para Parquet, CSV ou buffers Arrow. É OLAP sem cluster: consultas analíticas rodam dentro do seu processo, na mesma máquina do seu app ou worker.

O que a trilha 2.0 significa para CTOs não é um único recurso mágico — é um marco de estabilidade e performance. Espere caminhos de I/O mais rápidos, mais folga para resultados grandes e ergonomia melhor para extensões e manipulação de arquivos. Se você vinha esperando uma major para padronizar, este é o sinal.

Benefícios concretos em que você pode confiar

  • Latência previsível: Execução colunar e vetorizada sobre storage local mantém os p95 apertados. Para datasets por tenant de 1–5 GB, agregações sub-segundo em instâncias comuns de 8–16 cores são o normal quando você projeta para localidade de cache.
  • Zero taxa por consulta: Consultas não te cobram. As instâncias, sim. Um único servidor classe c6i.2xlarge (8 vCPU, 16–32 GB de RAM) dá conta de milhares de renders de dashboard por dia com folga.
  • Privacidade e residência por padrão: Mantenha o analytics na região do tenant, ou até on-device. Nada de sincronismo transfronteiriço para um data plane de terceiros só para calcular usuários ativos diários.
  • Ergonomia de dev decente: Você envia SQL, não uma frota. Sem drivers para cuidar, sem conexões externas para tunar e sem tentativas opacas. O ciclo de vida é do seu app.

Decision framework: When to embed vs. warehouse

Não arranque seu warehouse. Trace uma linha. Se a maior parte do seu analytics de produto cair na coluna da esquerda, comece a embutir DuckDB. Se cair na da direita, mantenha o warehouse e otimize.

Use-case fit

  • Ótimo para DuckDB: Dashboards por tenant, análise de coorte em 10–100M de linhas, agregações por janela de tempo, filtros interativos com 3–8 dimensões, exploração de feature store, ingestão e QA de CSV/Parquet, analytics offline em desktop/mobile.
  • Fique com o warehouse: joins cross-tenant sobre TBs de dados, centenas de usuários concorrentes consultando o mesmo dataset, padrões de acesso com joins demorados, políticas de governança centralizadas no warehouse, times de BI construindo modelos federados.

Rough sizing thresholds

  • Dados por tenant abaixo de ~10 GB comprimidos: Forte candidato a embutir. Maior ainda é viável com particionamento e streaming, mas teste a folga de memória.
  • Consultas concorrentes por instância abaixo de ~20: DuckDB escala verticalmente; você vai multiplexar com threads do app ou rodar workers por tenant. Se precisar de 200+ consultas pesadas concorrentes sobre o mesmo dado, um warehouse será operacionalmente mais simples.
  • Freshness = minutos a horário: Embutido brilha quando você consegue atualizar snapshots em agenda ou fazer append em Parquet particionado. Se precisar de atualizações segundo a segundo entre tenants, mantenha o caminho via warehouse para esses fluxos.

Risk controls

  • Nada de SQL arbitrário fornecido por usuário: Não deixe o app ou um LLM improvisar SQL. Compile uma pequena DSL para SQL parametrizado. Um post recente de dev foi direto: não dê SQL para o modelo. Você vai entregar com mais segurança e rapidez.
  • Isolamento por arquivo: Um arquivo por tenant ou por workspace. Nada de compartilhamento cross-tenant em disco. Isso torna snapshots, backup e deleção tratáveis.
  • Higiene de extensões: Só faça whitelist de extensões auditadas. Embutido significa que o seu processo é o raio de explosão.

Reference architectures you can ship this quarter

1) Server-embedded OLAP per tenant

Padrão: Para cada tenant, mantenha um lake Parquet particionado no object storage. Na consulta, seu app sobe uma conexão DuckDB, anexa o diretório Parquet, executa SQL parametrizado e retorna JSON para a UI. Faça cache de agregados quentes no Redis com TTL.

  • Prós: Infra mínima, custo previsível, auditoria fácil. Snapshots são apenas versionamento do object storage. Ótimo para 1–10k tenants com tráfego leve a moderado.
  • Contras: Você vai gerenciar contenção de CPU em nós compartilhados. Cold starts pagam um imposto de I/O a menos que você fixe partições quentes em NVMe local.

2) Worker-driven materialization

Padrão: Streams de eventos caem em arquivos colunares (Parquet). Um worker periódico (15–60 minutos) compacta e atualiza tabelas derivadas (rollups, tiles) com DuckDB. O app serve resultados pré-agregados com filter pushdown.

  • Prós: P95 abaixo de 200 ms para dashboards repetitivos. Muito barato de escalar. Fácil de impor SLAs.
  • Contras: Menos interativo para drill-downs arbitrários além dos formatos pré-computados.

3) On-device analytics com WebAssembly

Padrão: Para produtos client-heavy, faça preload do duckdb-wasm e envie fatias de dados criptografadas para o browser ou desktop. Execute consultas localmente; envie de volta apenas agregados para auditoria ou sincronização.

  • Prós: Custo zero de servidor por consulta, interatividade instantânea, postura forte de privacidade. Ideal para clientes enterprise que não deixam seus dados sair da VPC sem briga.
  • Contras: Tamanho do pacote, limites de memória e complexidade de atualização. Você precisa de uma estratégia robusta de conteúdo para os pacotes de dados.

4) Híbrido com um serviço DuckDB hospedado

Padrão: Use um serviço hospedado compatível com DuckDB para colaboração, semântica multi-writer ou compartilhamento de SQL (por exemplo, analistas iterando em métricas), enquanto o caminho do seu app permanece embutido para as consultas em runtime.

  • Prós: O melhor dos dois mundos para times com analistas que exigem ergonomia de SQL sem impor um warehouse no caminho do produto.
  • Contras: Você vai gerenciar dois caminhos — mantenha o caminho crítico do produto embutido para proteger latência e custo.

Performance and capacity planning that won’t surprise you

Shape your data for CPU caches

  • Colunar de ponta a ponta: Armazene em Parquet por padrão. Escolha tipos de coluna sensatos. Codifique categóricos; evite texto livre nos caminhos quentes.
  • Particione onde importa: Tempo (por mês/semana) e IDs de tenant/workspace. Isso reduz drasticamente o volume de varredura.
  • Tile para visuais pesados: Pré-compute tiles 256×256 de heatmap, buckets de histograma ou tabelas de percentis. Depois filtre e monte sob demanda.

Know your memory envelope

  • Mire 1–2× o tamanho dos dados comprimidos como working set seguro para group-bys complexos. Se os dados comprimidos de um tenant têm 6 GB, planeje 8–12 GB de folga de RAM ao executar suas consultas interativas mais pesadas.
  • Fixe partições quentes em NVMe se você depende de cold scans frequentes; DuckDB adora banda de leitura local rápida. Use object storage para a cauda longa.
  • Controle a concorrência com um token bucket simples por nó. Não deixe 30 consultas simultâneas de 8 cores brigarem em uma máquina de 16 cores.

Security and governance in an embedded world

  • Row-level security fica na sua camada de app: Com um arquivo por tenant, sua lógica de autorização permanece simples: ou você pode montar aquele dataset, ou não pode. Evite arquivos cross-tenant que forçam políticas complexas de RLS.
  • Superfície de SQL: Construa uma API segura que compile a intenção do usuário para templates de SQL. Nada de acesso arbitrário ao filesystem, criação de UDF ou escapes de shell. Audite cada instrução executada com parâmetros.
  • Criptografia e deleção: Criptografe em repouso via chaves do object storage, mais chaves de aplicação se você enviar para dispositivos cliente. Embuta deleção no ciclo de vida das partições; prove a eliminação com tombstones de versões de objetos e revogação de chaves.
  • Backups são cópias de arquivos: Faça snapshot de diretórios Parquet. Verifique a restauração subindo uma instância de staging de hora em hora com o snapshot mais recente e rodando uma smoke suite.

Costs that actually get better with scale

Aqui vai uma comparação conservadora de orçamento para um SaaS em meio de estágio servindo 50k visualizações de dashboard/dia:

  • Caminho via warehouse: 50k consultas × US$ 5/1.000 = US$ 250/dia em taxas de consulta (~US$ 7,5k/mês), mais storage, reservas de compute e egress. Realisticamente, US$ 10–20k/mês só para a fatia de analytics de produto.
  • Caminho embutido: 3× instâncias classe c7i.2xlarge (~US$ 350/mês cada) + storage/NVMe + engenharia nearshore para entregar e manter. Infra: ~US$ 1,5–3k/mês. Engenharia amortizada: depende do seu time, mas a maioria vê payback em 2–4 meses versus as contas do warehouse.

Nada disso conta o delta de latência visível ao usuário (sub-segundo versus segundos). Dashboards mais rápidos convertem trials, reduzem abandono e cortam tickets de suporte — benefícios que o financeiro não captura bem, mas suas métricas de crescimento sim.

30/60/90: um plano de rollout pragmático

Dias 0–30: inventário e piloto

  • Logue hoje no seu app todo o shape de consulta de dashboard: dimensões, filtros, janelas de tempo e tamanhos de resultado. Você vai descobrir que 80% caem em uma dúzia de padrões.
  • Levante um repositório piloto embutindo DuckDB na linguagem principal do seu app. Conecte a um snapshot Parquet por tenant. Reconstrua os três dashboards mais pesados com SQL parametrizado.
  • Golden tests: Valide igualdade com os resultados do seu warehouse em snapshots fixos. Torne isso repetível no CI.

Dias 31–60: endurecimento operacional

  • Particionamento e compactação: Construa o job de compactação para criar Parquet particionado para cada tenant diariamente ou por hora, conforme a necessidade de freshness.
  • Estratégia de cache: Adicione um cache de 5–15 minutos por agregado caro. Mostre “dados até HH:MM” na UI.
  • Controles de concorrência: Introduza um token bucket por nó. Faça fail-fast para o cache, ou degrade para tiles pré-computados sob carga.
  • Postura de segurança: Trave extensões. Remova primitivas de filesystem da superfície de SQL. Armazene cada instrução executada para auditoria.

Dias 61–90: inverta o padrão com segurança

  • Dark launch: Direcione 10–20% dos tenants para o embutido, meça latência P50/P95 e correção. Avance para 50–70% se o orçamento de erro aguentar.
  • Controles de custo: Corte o compute do warehouse para essa fatia. Mantenha um caminho de “break glass” por duas semanas enquanto você monitora.
  • Habilitação do time: Publique seus templates de SQL e docs da DSL. Treine PMs/analistas sobre o que é possível na UI versus o que fica no warehouse.

Trade-offs que você precisa aceitar

  • Escala vertical, não horizontal: DuckDB adora muitos cores e discos locais rápidos. Se o seu modelo mental é “adicionar um nó, ficar mais rápido”, você vai se frustrar. Em vez disso, faça sharding por tenant ou workspace.
  • Realidades de single-writer: Concorrência é tranquila para leituras; jobs de compactação e materialização devem ser agendados para evitar conflitos frontais. Se você realmente precisa de multi-writer com alta concorrência, um serviço hospedado compatível com DuckDB ou seu warehouse pode fazer sentido para caminhos de autoria.
  • Tolerância limitada a consultas longas: Embutido é o lugar errado para joins de 5–30 minutos. Coloque timebox nas consultas e desenhe a UX para incentivar caminhos pré-computados para trabalhos grandes.
  • Você é dono da correção: Não há “serviço misterioso” para culpar. A boa notícia: seus snapshots de teste, golden queries e CI podem provar a correção a cada release.

Por que isso é um movimento nearshore-friendly

Analytics embutido paga mais rápido quando você consegue iterar no codebase do app com ciclos de feedback curtos. Esse é o sweet spot de nearshore: 6–8 horas de sobreposição com os fusos dos EUA, baixa sobrecarga de integração e entregáveis claros (dashboards X/Y/Z migrados para embutido; P95 abaixo de 800 ms; US$ N economizados/mês). Rotineiramente vemos um pod pequeno — 1 backend sênior, 1 data engineer, 1 full-stack — entregar um piloto em 3–4 semanas e virar 60% do analytics de produto em um trimestre.

O bottom line

Warehouses não vão desaparecer. Mas se você os usa para renderizar dashboards por tenant, é como comprar um carro de Fórmula 1 para dirigir dentro de um shopping. Com o amadurecimento do DuckDB 2.0, OLAP embutido é o padrão sensato para analytics voltado ao produto: mais barato, mais rápido e mais simples de operar. Trace sua linha e mova o lado esquerdo — agora.

Key Takeaways

  • Não coloque um warehouse para dashboards por tenant; incorpore DuckDB e mantenha o analytics no seu app.
  • Mire datasets por tenant abaixo de ~10 GB comprimidos e menos de 20 consultas pesadas concorrentes por nó.
  • Armazene dados em Parquet particionado, compile a intenção do usuário para SQL parametrizado e regule a concorrência.
  • Espere P95 sub-segundo para agregados comuns em instâncias de 8–16 cores e uma redução de custo de 3–10× versus serviços por consulta.
  • Faça o rollout em 90 dias: pilote 3 dashboards, endureça compactação/cache, faça dark launch para 20–70% dos tenants e depois corte o gasto de warehouse para essa fatia.

Ready to scale your engineering team?

Tell us about your project and we'll get back to you within 24 hours.

Start a conversation