Pular para o conteúdo
/blog /

Multi-tenant do zero: o que ninguém te conta antes de começar

Lições de arquitetura aprendidas construindo um ERP multi-tenant com 11 milhões de itens em estoque.

Multi-tenant Arquitetura PostgreSQL Next.js

Multi-tenant parece simples na cabeça: “ah, é só ter uma coluna tenant_id em tudo”. Acabou de te dar uma falsa sensação de simplicidade. Vou contar o que aprendi na prática.

A decisão das três estratégias

Existem três modelos, e a escolha errada custa caro:

  1. Database por tenant — isolamento máximo, custo operacional alto.
  2. Schema por tenant — meio termo, complexo para migrações.
  3. Tabelas compartilhadas com tenant_id — escala melhor, exige disciplina.

Para o ERP de gestão de lojas, escolhi a terceira. Razão: precisava de relatórios cross-tenant (super-admin) e o custo operacional dos outros modelos não justificava.

Onde a coisa quebra

Esquecer o tenant_id em uma única query é vazamento de dados. A solução não é “ter cuidado” — é tornar impossível esquecer:

// Não confie no dev. Confie no código.
const db = createTenantScopedClient(tenantId);

// Toda query nasce com WHERE tenant_id = ? automático.
await db.products.findMany();

Postgres tem Row Level Security que faz isso no banco. Eu uso em camadas duplas: RLS no banco + escopo na aplicação. Belt and suspenders.

Migrações multi-tenant doem

Migration que demora 30s em uma tabela de 10k linhas demora 5h numa tabela de 11M. Aprendi:

  • CREATE INDEX CONCURRENTLY sempre.
  • ALTER TABLE ... ADD COLUMN com DEFAULT em Postgres 11+ é instantâneo. Antes disso, era pesadelo.
  • Para refactors grandes: dual-write, backfill, switch, cleanup. Quatro deploys, não um.

Feature flags por tenant: indispensável

Cada cliente é um cliente. Recurso novo? Liga pra um, espera feedback, depois pra todos. Sem flag por tenant, você libera bug pra 100 ao mesmo tempo.

if (await flags.enabled("nova-tela-estoque", tenantId)) {
  // ...
}

Observabilidade tem que ter tenant_id em tudo

Log sem tenant_id é log inútil. Trace sem tenant_id é trace inútil. Métrica sem tenant_id te impede de saber qual cliente está sofrendo.

Conclusão

Multi-tenant é uma decisão de arquitetura que afeta absolutamente tudo depois. Pense duas vezes antes, e quando começar, escolha consistência sobre engenhosidade.