Multi-tenant database design

Este post ainda não está disponível no seu idioma. Mostrando a versão em inglês.

engineering

Multi-tenant database design

Shared schema, schema-per-tenant, or database-per-tenant — picking the model before the first row lands.

Alexandre Awadallak2 min read

Most SaaS products pick their multi-tenancy model once and live with it forever. The migration cost later is so high that teams build entire companies around the constraints of a decision they made in their first sprint.

Shared schema with a tenant_id column#

Every row carries org_id. One database, one schema, one set of connections. Cheap to operate and dead simple until you need a row-level security policy that a junior engineer can't accidentally bypass. Postgres RLS helps. Discipline helps more.

Schema-per-tenant#

A new Postgres schema for each organization. Stronger isolation, but migrations now have to run N times, and your connection pool has to juggle N search_path switches. Works well up to a few hundred tenants. Beyond that, schema metadata overhead in Postgres becomes a real cost.

Database-per-tenant#

The nuclear option. Used by enterprise-heavy SaaS where customers demand guaranteed isolation, or by verticals under regulatory pressure (healthcare, finance). Each tenant gets their own database instance. Eye-watering cost at scale, near-perfect blast radius.

The pragmatic default#

For a new SaaS today, shared-schema with org_id scoping on every query is almost always the right answer. Add RLS when you can. Build a habit of writing WHERE org_id = $1 as reflexively as semicolons.

When to reconsider#

Consider migration when a single tenant's data volume dwarfs everyone else, or when you land an enterprise customer whose procurement document uses the word "dedicated."