SobreProjetosServiços BlogFAQContato
Início/Blog/Dados e infraestrutura
Dados e infraestrutura

Multi-tenant: como isolar dados de cada cliente

Compare as três estratégias de isolamento em sistemas multi-tenant, coluna com RLS, schema por cliente e banco por cliente, com custos e riscos de cada uma.

30 de mar. de 2026 5 min de leitura por Natiam Gabriel
Multi-tenant: como isolar dados de cada cliente
Resposta curta

Existem três formas de isolar dados por cliente: coluna tenant_id com Row Level Security, um schema por cliente ou um banco por cliente. Para a maioria dos SaaS, RLS no PostgreSQL é o melhor equilíbrio, porque o isolamento passa a ser garantido pelo banco e não pela disciplina de quem escreve a consulta.

Em um sistema que atende vários clientes na mesma instalação, o isolamento de dados pode ser feito de três formas: coluna tenant_id protegida por Row Level Security, um schema por cliente ou um banco de dados por cliente. Para a maioria dos SaaS, a primeira opção com RLS ativo é a escolha certa, porque transfere a garantia do isolamento do código para o banco. As outras duas entram quando o contrato ou o volume exigem.

Comparativo entre as três estratégias

Critério tenant_id + RLS Schema por cliente Banco por cliente
Força do isolamento Alta, garantida pelo banco Alta Máxima
Custo por cliente novo Quase zero Baixo Alto
Complexidade de migração de schema Uma vez Repetida por schema Repetida por banco
Restaurar backup de um cliente só Difícil Médio Trivial
Limite prático de clientes Milhares Centenas Dezenas a poucas centenas
Consulta agregada entre clientes Simples Média Difícil
Encaixa exigência de "dado separado" Às vezes não convence Parcialmente Sim

Opção 1: tenant_id com Row Level Security

Todas as tabelas ganham uma coluna tenant_id. Até aí, é o modelo que quase todo mundo usa. A diferença está em quem garante o filtro.

Filtrar na aplicação funciona até o dia em que alguém escreve um relatório novo às pressas e esquece o WHERE tenant_id = ?. Não é hipótese: é o modo de falha mais comum de sistema multi-tenant, e o resultado é dado de um cliente aparecendo na tela de outro.

Row Level Security resolve isso no PostgreSQL. Você ativa a política na tabela e o banco passa a aplicar o filtro sozinho, em qualquer consulta:

ALTER TABLE pedidos ENABLE ROW LEVEL SECURITY;
ALTER TABLE pedidos FORCE ROW LEVEL SECURITY;

CREATE POLICY tenant_isolado ON pedidos
 USING (tenant_id = current_setting('app.tenant_id')::uuid);

A aplicação define app.tenant_id no início de cada transação, a partir da sessão autenticada. Uma consulta sem filtro passa a retornar zero linhas em vez de retornar tudo. Erro de programação vira ausência de dado, não vazamento.

Três cuidados que costumam ser esquecidos:

  • FORCE ROW LEVEL SECURITY é necessário porque o dono da tabela, por padrão, ignora as políticas. Rode a aplicação com um usuário que não seja o dono.
  • Índices compostos começando por tenant_id ((tenant_id, criado_em)), senão o desempenho cai conforme a base cresce.
  • Rotinas de manutenção e relatórios rodam fora do contexto da requisição e precisam de um caminho explícito e auditado.

Opção 2: um schema por cliente

Cada cliente ganha um schema próprio dentro do mesmo banco, com as mesmas tabelas. A aplicação define o search_path de acordo com o cliente conectado.

Vantagens reais: separação visível, backup e restauração por schema mais simples, e a possibilidade de um cliente ter uma coluna extra sem afetar os outros.

O custo aparece na manutenção. Toda alteração de estrutura precisa rodar em todos os schemas, o que vira um processo demorado e sujeito a divergência quando são centenas. Bancos com muitos milhares de tabelas também sofrem no planejador de consultas e no tempo de dump.

Faz sentido para dezenas ou poucas centenas de clientes corporativos, especialmente se houver customização por cliente.

Opção 3: um banco por cliente

Isolamento máximo. Vazamento entre clientes deixa de depender do código e passa a depender de credencial. Restaurar apenas o cliente que apagou dados por engano fica trivial. Cliente grande com exigência de "base separada" no contrato fica atendido sem discussão.

O preço é operacional e cresce linear com a base de clientes: cada banco precisa de migração, backup, monitoramento, ajuste de conexão e recursos mínimos. Trinta clientes com trinta bancos ainda dá para automatizar; trezentos exigem ferramental próprio e alguém dedicado.

Sinais de que essa é a opção certa: poucos clientes de ticket alto, exigência contratual ou regulatória de separação física, ou necessidade de manter clientes em regiões diferentes.

O modelo híbrido, que é o mais usado na prática

A arquitetura que costuma sobreviver ao crescimento não escolhe uma só:

  • Padrão: todos os clientes em banco compartilhado, com tenant_id e RLS.
  • Exceção: clientes que exigem por contrato, ou que sozinhos representam volume desproporcional, ganham banco dedicado.
  • Requisito de projeto: a aplicação resolve a conexão a partir do identificador do cliente, sem saber se ele está no banco compartilhado ou no dedicado.

Se essa resolução de conexão for construída desde o começo, mesmo que exista um único banco, promover um cliente para base dedicada depois vira configuração, e não reescrita. É o padrão que usamos nos sistemas multi-tenant que a Retti Tech mantém em produção.

Isolamento não termina no banco

Dado separado no banco e misturado no resto não isola nada. Verifique também:

  • Arquivos enviados. Prefixo por cliente no armazenamento e URLs assinadas com prazo, nunca caminho previsível e público.
  • Cache. Chave de cache sem o identificador do cliente é a forma mais silenciosa de vazar dado entre clientes.
  • Filas e tarefas em segundo plano. O worker precisa reestabelecer o contexto do cliente ao processar a mensagem, fora da requisição HTTP, o RLS não tem de onde tirar o tenant_id.
  • Busca e índices vetoriais. Em sistemas com RAG, o filtro por cliente tem que entrar na consulta ao índice, não na filtragem posterior.
  • Logs e mensagens de erro. Rastro de exceção com dado de cliente vai parar em ferramenta de terceiro.

Como testar se o isolamento funciona

Não confie na leitura do código. Escreva testes automatizados que provem a separação:

  1. Crie dois clientes com dados semelhantes.
  2. Autentique como o cliente A e tente ler, alterar e apagar um registro do cliente B pelo identificador direto.
  3. Repita para cada endpoint da API, inclusive relatórios e exportações.
  4. Verifique que a resposta é 404 ou 403, nunca o dado.
  5. Repita o teste para arquivos, cache e tarefas em segundo plano.

Esses testes precisam rodar em cada alteração. Isolamento é o tipo de propriedade que quebra em silêncio: nada falha, nada dá erro, e alguém simplesmente enxerga o que não deveria.

Perguntas frequentes

Qual a forma mais segura de isolar dados em multi-tenant?

Banco separado por cliente é a mais segura, porque o vazamento entre clientes exige uma falha de credencial, não um bug de consulta. O custo operacional é o mais alto: migrações, backups e monitoramento se multiplicam por cliente.

Filtrar por tenant_id na aplicação é suficiente?

É o padrão mais comum e o mais frágil. Basta um desenvolvedor esquecer o filtro em uma consulta para expor dado de outro cliente. Se optar por esse caminho, o filtro precisa ser imposto por Row Level Security no banco, não confiado ao código.

Dá para começar com um modelo e mudar depois?

Dá, e é o caminho normal. Comece com tenant_id e RLS, que serve a maior parte dos casos, e migre para banco dedicado apenas os clientes que exigirem por contrato. Modelos híbridos são comuns em SaaS que atendem empresas grandes.

Tem um processo que consome o time?

Me conta como funciona hoje. Se der para automatizar, eu te digo por onde começar — a conversa de diagnóstico não é cobrada.

Natiam Gabriel
Sobre o autor

Natiam Gabriel é AI Engineer & Full-Stack Developer e fundador da Retti Tech, estúdio de desenvolvimento de software que atende empresas em todo o Brasil. Constrói sistemas web sob medida, automações e integrações, com ou sem inteligência artificial, do levantamento de requisitos até a operação em produção. Mais de 20 empresas usam em produção os sistemas que desenvolveu.