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 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:
- Database por tenant — isolamento máximo, custo operacional alto.
- Schema por tenant — meio termo, complexo para migrações.
- 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 CONCURRENTLYsempre.ALTER TABLE ... ADD COLUMNcomDEFAULTem 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.