Multitenancy: Cómo servir a miles de clientes con una sola aplicación

Jorge SaavedraJorge Saavedra
·12 de julio, 2025·8 min de lectura
spring-bootpostgresqlarquitecturamultitenancybases-de-datosgo
Tienes una aplicación que funciona perfecto para un cliente. Ahora te piden que sirva a 500 clientes sin duplicar la infraestructura. Multitenancy es la respuesta: un modelo arquitectónico que permite que la misma aplicación e infraestructura sirva a múltiples clientes independientes de manera eficiente y segura.

¿Qué es multitenancy?

Multitenancy es un modelo arquitectónico en el que la misma aplicación y, por lo general, la misma infraestructura de bases de datos y servidores, atiende a varios clientes independientes a los que llamamos tenants o inquilinos. Cada tenant tiene sus propios usuarios, datos y configuraciones. No puede acceder ni interferir con la información de otro tenant. Y desde su perspectiva, la aplicación es completamente suya, aunque en realidad la comparte con todos los demás.
Piensa en un edificio de oficinas. El edificio es tu aplicación y toda la infraestructura que la sostiene. Cada oficina dentro del edificio es un tenant. Todos comparten la misma estructura física: los ascensores, la electricidad, el internet. Pero cada oficina tiene su propia llave, su propio acceso controlado y su propia decoración. No puedes entrar a la oficina del vecino, y él no puede entrar a la tuya. Multitenancy funciona exactamente así.

Tipos de multitenancy

Aunque el concepto es uno solo, la implementación puede variar bastante. Hay tres modelos principales que se usan en la industria, y cada uno resuelve el problema del aislamiento de datos de una forma diferente.

1. Aislamiento lógico en la base de datos

Este es el modelo más común y el más eficiente en términos de recursos. Hay una sola instancia de base de datos donde todas las tablas contienen los datos de todos los tenants. Lo que separa los datos de un cliente de los de otro es un simple campo: tenant_id. Cada fila en cada tabla tiene este campo, y todas las consultas de la aplicación filtran por él.
El aislamiento se logra en dos capas. A nivel de aplicación, todas las consultas incluyen un WHERE tenant_id = ?. A nivel de base de datos, se pueden agregar políticas de Row-Level Security (RLS) como segunda línea de defensa, para que incluso si un desarrollador olvida el filtro, la base de datos no entregue datos que no correspondan.
Así se ve en la práctica. Misma tabla, misma base de datos, pero los datos de cada cliente están claramente separados por su tenant_id:
idtenant_idemailname
1acme_corpana@acme.comAna
2nova_techluis@novatech.ioLuis
3acme_corpcarlos@acme.comCarlos
4nova_techmaría@novatech.ioMaría
sql
-- Ejemplo de tabla con tenant_id
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    tenant_id UUID NOT NULL,
    email VARCHAR(255) NOT NULL,
    name VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Índice para optimizar consultas por tenant
CREATE INDEX idx_users_tenant_id ON users(tenant_id);

-- Row Level Security (RLS) para garantizar aislamiento
ALTER TABLE users ENABLE ROW LEVEL SECURITY;

-- Política que solo permite ver datos del tenant actual
CREATE POLICY tenant_isolation ON users
    USING (tenant_id = current_setting('app.current_tenant_id')::UUID);
Este modelo es muy eficiente: un solo pool de conexiones, un solo esquema que mantener, y agregar un tenant nuevo es tan simple como insertar una fila. Empresas como Slack y Trello lo usan: cada workspace o equipo es un tenant, pero los datos viven en las mismas bases de datos distribuidas. La desventaja es que un bug en las consultas que olvide filtrar por tenant_id puede exponer datos de un cliente a otro. Por eso Row-Level Security es tan importante como red de seguridad.

2. Esquema dedicado por tenant

En este modelo hay una sola instancia de base de datos, pero cada tenant tiene su propio esquema dentro de ella. En PostgreSQL, por ejemplo, Acme Corp tendría el esquema acme_corp y Nova Tech el esquema nova_tech. Cada esquema tiene sus propias tablas con la misma estructura, pero los datos están físicamente separados dentro de la misma base.

Modelo de Esquemas Dedicados

API ServerTenant: Acme CorpTenant: Nova TechUna sola instancia de PostgreSQLAcme Corpschema: acme_corpusersid | email | name1 | ana@acme.com | Ana2 | carlos@acme.com | Carlosordersid | user_id | total | status1 | 1 | $2,400 | completado2 | 2 | $890 | pendienteNova Techschema: nova_techusersid | email | name1 | luis@novatech.io | Luis2 | maría@novatech.io | Maríaordersid | user_id | total | status1 | 1 | $1,200 | completado2 | 2 | $3,500 | completadoMisma estructura, datos completamente separados
sql
-- Creación de esquemas por tenant
CREATE SCHEMA acme_corp;
CREATE SCHEMA nova_tech;

-- Tablas en esquema dedicado
CREATE TABLE acme_corp.users (
    id SERIAL PRIMARY KEY,
    email VARCHAR(255) NOT NULL,
    name VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE nova_tech.users (
    id SERIAL PRIMARY KEY,
    email VARCHAR(255) NOT NULL,
    name VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
La ventaja principal es que el aislamiento es más fuerte que en el modelo lógico: no hay riesgo de filtración por un WHERE olvidado, porque las tablas directamente no se comparten. También permite migraciones más controladas, donde puedes probar un cambio de esquema en un tenant antes de aplicarlo a todos. La desventaja es que cada nuevo cliente requiere crear un esquema completo con todas sus tablas, y si tienes miles de tenants la cantidad de esquemas en una sola base se vuelve difícil de manejar. Este modelo funciona bien para aplicaciones B2B con pocos clientes grandes que necesitan personalizaciones específicas.

3. Base de datos dedicada por tenant

Este es el modelo con mayor nivel de aislamiento. Cada tenant tiene su propia base de datos, que incluso puede estar en un servidor distinto. La aplicación central actúa como un router que, en función del tenant que hace la solicitud, redirige la conexión a la base de datos correcta.

Modelo de Bases de Datos Dedicadas

API Gateway + Tenant RouterAcme CorpPostgreSQLacme_dbDatos cifradosNova TechMySQLnova_dbPlan estándarBanco CentralPostgreSQLbanco_dbHIPAA CompliantCada tenant tiene su propia base de datos y puede estar en un servidor distinto
El aislamiento es casi total, lo que lo convierte en la opción preferida para clientes en sectores regulados como la banca o la salud, donde normas como HIPAA o GDPR pueden exigir separación física de los datos. También permite escalar cada tenant de forma independiente: si un cliente necesita más recursos, puedes asignarle un servidor más potente sin afectar a los demás. El precio es la complejidad operativa, ya que cada tenant implica mantener, monitorizar y migrar una base de datos adicional. La automatización se vuelve obligatoria.

Comparativa rápida

ModeloAislamientoCosteEscalabilidadComplejidad
Lógico (tenant_id)Bajo-MedioBajoAltoBaja
Esquema dedicadoMedioMedioMedio-AltoMedia
Base dedicadaAltoAltoMedioAlta

¿Cuál elegir?

La decisión depende de cuatro factores. Si tus clientes están en sectores con normas estrictas como banca o salud, el aislamiento físico puede ser obligatorio. Si necesitas escalar a miles de clientes, el aislamiento lógico es la opción más manejable. Si algunos tenants requieren cambios grandes en la estructura de datos o configuraciones muy particulares, un esquema o base dedicada tiene más sentido. Y si el presupuesto es una restricción importante, hay que tener en cuenta que las bases dedicadas implican un coste operativo mucho más alto.
En la práctica, muchas empresas combinan modelos. Shopify usa aislamiento lógico para la mayoría de sus tiendas, pero ofrece infraestructura dedicada a sus clientes enterprise. Salesforce, pionero en SaaS multitenant, corre la mayor parte de sus organizaciones en infraestructura compartida con aislamiento lógico. Atlassian hace algo similar con Jira y Confluence. El punto es que no tienes que elegir uno solo: puedes empezar con el modelo más simple y migrar tenants específicos a infraestructura dedicada cuando el negocio lo justifique.

El riesgo principal: data leakage

El mayor riesgo en multitenancy con aislamiento lógico es una consulta que olvida filtrar por tenant_id. Un solo bug puede exponer datos de un cliente a otro, y ese tipo de incidente puede destruir la confianza de todos tus clientes de un golpe. La mejor forma de prevenirlo es implementar Row-Level Security a nivel de base de datos como segunda línea de defensa, y agregar tests automatizados que verifiquen explícitamente que un tenant no puede ver datos de otro.

Buenas prácticas

En seguridad, incluye el tenant_id en el token JWT para que el contexto del tenant viaje con cada request. Aplica filtros tanto en la capa de aplicación como en la base de datos con RLS, y asegúrate de que todos los logs incluyan el tenant_id para facilitar la auditoría y la depuración.
En performance, implementa rate limiting por tenant para evitar que un cliente acapare todos los recursos. Crea índices optimizados que incluyan el tenant_id en todas las tablas principales, y si usas cache, incluye el tenant_id en las claves para evitar colisiones entre clientes.
En operaciones, automatiza todo lo que puedas: el alta de nuevos tenants, las migraciones de base de datos, y el monitoreo. Cuando tienes decenas o cientos de tenants, hacer cualquier cosa de forma manual se vuelve insostenible. Configura métricas y alertas segmentadas por tenant para poder detectar problemas que afectan a un solo cliente sin que se pierdan en el ruido del promedio general.

Conclusión

El multitenancy es un patrón clave para construir aplicaciones SaaS escalables y eficientes. Elegir el modelo correcto depende de tu tipo de clientes, tus requisitos de seguridad y tu presupuesto. Ya sea que uses un solo esquema con tenant_id o una base de datos por cliente, el objetivo es el mismo: servir a muchos como si sirvieras a uno, garantizando seguridad, personalización y eficiencia.
En la próxima entrega veremos la implementación práctica: cómo construir una aplicación multitenant con aislamiento lógico paso a paso, incluyendo interceptors, Row-Level Security en PostgreSQL, y tests que validen que un tenant no puede ver datos de otro.
¿Tienes experiencia implementando multitenancy? ¿Qué desafíos has encontrado? Me encantaría conocer tu perspectiva.

Posts que podrian interesarte