Substituímos Nosso Snowflake de $8k/mês por DuckDB e Parquet
Esta é a história de como fomos de $8.000/mês no Snowflake para $0/mês — sem perder nada que importava para nossa equipe de 12 analistas.
O Problema
Nossa conta do Snowflake crescia 20% mês a mês. Tínhamos:
- 2,3 TB de dados em 47 tabelas
- 12 analistas executando consultas
- 90% das consultas eram simples: agregações, filtros, joins em 3-4 tabelas
- A consulta média escaneava menos de 50 GB
- O warehouse ficava ocioso 18 horas/dia
Estávamos pagando preços de data warehouse enterprise para cargas de trabalho que um laptop poderia lidar.
A Descoberta
Arquivos Parquet no S3 + DuckDB = um data warehouse grátis para nossa escala.
O DuckDB pode:
- Ler Parquet diretamente do S3 (sem COPY INTO, sem staging)
- Executar SQL complexo com joins, window functions, CTEs
- Processar 50 GB em segundos em uma única máquina
- Fazer cache de resultados para consultas repetidas
A peça que faltava era ferramental. Precisávamos de:
- Descoberta de tabelas (o que tem no bucket?)
- Gerenciamento de schema (quais colunas existem?)
- Uma interface de consulta para analistas
- Integração de IA para usuários de negócio
O DataSpoc Lens forneceu tudo isso.
A Migração
Passo 1: Exportar do Snowflake para Parquet
Já tínhamos nossos dados brutos no S3 (o Snowflake carregava de lá). Para tabelas curadas, exportamos:
pip install dataspoc-pipe
# We used Pipe to extract our Snowflake curated tables to Parquetdataspoc-pipe add snowflake \ --account xy12345.us-east-1 \ --database ANALYTICS \ --schema CURATED \ --tables revenue,customers,products,orders,sessions \ --destination s3://company-lakeA migração única levou 15 minutos para 2,3 TB.
Passo 2: Apontar o Lens para o Bucket
pip install dataspoc-lens
dataspoc-lens add-bucket s3://company-lakedataspoc-lens discoverSaída:
Discovered 47 tables in s3://company-lake: raw/postgres/orders (1.2M rows, 340 MB) raw/postgres/customers (89K rows, 12 MB) raw/postgres/products (2.4K rows, 1.1 MB) curated/finance/revenue (4.2M rows, 890 MB) curated/product/sessions (12M rows, 2.1 GB) ...Passo 3: Consultar Como no Snowflake
O SQL é idêntico. Cada consulta que tínhamos no Snowflake funcionou no DuckDB sem modificação:
Snowflake:
-- snowflake worksheetSELECT DATE_TRUNC('month', order_date) AS month, product_category, SUM(amount) AS revenue, COUNT(DISTINCT customer_id) AS unique_customersFROM analytics.curated.revenueWHERE order_date >= '2024-01-01'GROUP BY 1, 2ORDER BY 1, 2;DataSpoc Lens (mesmo SQL):
dataspoc-lens query "SELECT DATE_TRUNC('month', order_date) AS month, product_category, SUM(amount) AS revenue, COUNT(DISTINCT customer_id) AS unique_customersFROM curated.finance.revenueWHERE order_date >= '2024-01-01'GROUP BY 1, 2ORDER BY 1, 2"Mesmos resultados. Custo zero. 1,2 segundos em vez de 3,4 segundos (warehouse XS do Snowflake).
Passo 4: Dar aos Analistas um Shell Interativo
dataspoc-lens shellDataSpoc Lens Shell (DuckDB 0.10.1)Connected to: s3://company-lake (47 tables)Type .tables to list, .schema <table> to inspect, .quit to exit
lens> .tables┌─────────────────────────────────┬──────────┬─────────┐│ table │ rows │ size │├─────────────────────────────────┼──────────┼─────────┤│ curated.finance.revenue │ 4.2M │ 890 MB ││ curated.product.sessions │ 12M │ 2.1 GB ││ raw.postgres.orders │ 1.2M │ 340 MB ││ raw.postgres.customers │ 89K │ 12 MB ││ ... │ │ │└─────────────────────────────────┴──────────┴─────────┘
lens> SELECT COUNT(*) FROM curated.finance.revenue WHERE order_date >= '2024-01-01';┌──────────┐│ count │├──────────┤│ 1847293 │└──────────┘(0.4s)Analistas que sabiam SQL foram produtivos imediatamente. Sem retreinamento.
Passo 5: IA Ask para Usuários de Negócio
Para o CEO e PMs que não escrevem SQL:
dataspoc-lens ask "What was our MRR growth last quarter?"Based on curated.finance.revenue:
MRR grew from $1.23M (Jul 2024) to $1.47M (Sep 2024), a 19.5% increaseover Q3. The strongest month was September (+8.2% MoM), driven byEnterprise plan upgrades.
SQL used: SELECT DATE_TRUNC('month', order_date) AS month, SUM(amount) AS mrr FROM curated.finance.revenue WHERE order_date >= '2024-07-01' AND order_date < '2024-10-01' AND revenue_type = 'recurring' GROUP BY 1 ORDER BY 1A IA mostra seu trabalho — a consulta SQL exata — para que analistas possam verificar.
Comparação de Performance
Fizemos benchmark das nossas 20 consultas mais comuns:
| Tipo de Consulta | Snowflake (XS) | DataSpoc Lens (DuckDB) |
|---|---|---|
| Agregação simples (1 tabela) | 1,8s | 0,3s |
| Join 2 tabelas + group by | 3,2s | 1,1s |
| Window function sobre 1M linhas | 4,1s | 1,8s |
| Full table scan 12M linhas | 6,7s | 4,2s |
| CTE complexo com 4 joins | 8,3s | 3,9s |
DuckDB foi mais rápido para cada consulta individual na nossa escala. O segredo: sem round-trip de rede para um warehouse na nuvem, o formato colunar do Parquet significa que o DuckDB só lê as colunas necessárias, e leituras S3 são paralelizadas.
A Comparação de Custos
| Centro de Custo | Snowflake | DataSpoc Lens |
|---|---|---|
| Compute (warehouse) | $6.200/mês | $0 |
| Armazenamento (gerenciado) | $1.800/mês | $0 (já pagando pelo S3) |
| Armazenamento S3 | $47/mês | $47/mês (mesmos dados) |
| Requisições S3 GET | — | $12/mês |
| Licença DataSpoc Lens | — | $0 (open source) |
| Total | $8.047/mês | $59/mês |
Economia anual: $95.856.
O Que Ganhamos
Além da economia de custos:
- Sem gerenciamento de warehouse. Sem dimensionamento, sem ajuste de auto-suspend, sem monitoramento de créditos.
- Início instantâneo. Sem cold-start do warehouse (15-45 segundos no Snowflake).
- Desenvolvimento local. Analistas podem consultar os mesmos dados localmente com
dataspoc-lens shell. - Nativo para IA. Servidor MCP significa que Claude, GPT e agentes internos consultam nossos dados diretamente.
- Portável. Sem lock-in de fornecedor. Parquet é um formato aberto.
O Que Perdemos (e ressalvas honestas)
Esta abordagem NÃO substitui o Snowflake se você tem:
| Requisito | Snowflake | DataSpoc Lens |
|---|---|---|
| 50+ analistas simultâneos | Lida com isso | Único usuário por processo |
| Dados em escala de petabytes | Compute distribuído | Máquina única (limite ~100 GB efetivo) |
| RBAC granular | Roles + políticas nativas | Baseado em IAM (nível de bucket) |
| Time travel / versionamento | Integrado | Você gerencia versões do Parquet |
| Semi-estruturado (JSON) | Tipo VARIANT | Funções JSON do DuckDB (funciona, menos elegante) |
| Governança / lineage | Nativo + parceiros | Faça você mesmo |
| Compartilhamento de dados | Secure shares | Compartilhe o bucket (menos governado) |
Nossa regra de ouro: Se seus dados cabem na memória de uma única máquina (até ~100 GB ativamente consultados), você provavelmente não precisa de um warehouse na nuvem. Isso cobre 80% das startups e empresas de médio porte.
O Playbook de Migração
Para equipes considerando isso:
- Audite seu uso do Snowflake. Execute
ACCOUNT_USAGE.QUERY_HISTORY— verifique volumes de dados e concorrência. - Se 90% das consultas escaneiam < 50 GB: você é candidato.
- Exporte tabelas curadas para Parquet no S3. Use DataSpoc Pipe ou
COPY INTOcom formato Parquet. - Configure o Lens.
pip install dataspoc-lens && dataspoc-lens add-bucket s3://your-bucket - Execute suas top 20 consultas. Valide correção e performance.
- Migre analistas gradualmente. Mantenha o Snowflake vivo por 1 mês como fallback.
- Desligue o warehouse.
# The full migration in 4 commandspip install dataspoc-pipe dataspoc-lens
dataspoc-pipe add snowflake --account YOUR_ACCOUNT --tables ALL --destination s3://your-lakedataspoc-pipe run
dataspoc-lens add-bucket s3://your-lakedataspoc-lens shell # You're doneUm Ano Depois
12 meses após a migração:
- Economizamos $95K em custos de Snowflake
- Performance de consultas melhorou (sem cold starts)
- Analistas estão mais satisfeitos (shell instantâneo, AI Ask)
- Zero incidentes relacionados à migração
- Adicionamos servidor MCP para que bots de produto consultem dados autonomamente
Os $8K/mês estavam comprando coisas que não precisávamos. Para equipes na nossa escala, o data warehouse na nuvem é um problema resolvido — e a solução é grátis.