Multitenancy: Cómo servir a miles de clientes con una sola aplicación
Fecha de publicación: 2025-01-15
Comparación de Modelos de Multitenancy
En el mundo del desarrollo de software SaaS, una de las decisiones arquitectónicas más importantes es cómo manejar múltiples clientes con una sola aplicación. Multitenancy es la respuesta elegante a este desafío: permite que la misma aplicación y 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 base de datos y servidores, atienden 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.
Siente que la aplicación es "suya", aunque en realidad la comparte con otros.
Analogía del edificio de oficinas
Imagina un edificio de oficinas:
El edificio = tu aplicación y la infraestructura
Cada oficina = un tenant (cliente)
Todos usan la misma estructura física (ascensores, electricidad, internet), pero cada oficina tiene llave propia, acceso controlado y decoración personalizada
Tipos de multitenancy
Aunque el concepto es único, la implementación puede variar bastante. Hay tres modelos principales que se usan en la industria:
1. Multitenancy con aislamiento lógico en la base de datos
En este modelo:
Hay una sola instancia de base de datos (p. ej., un PostgreSQL, MySQL, etc.)
Todas las tablas contienen los datos de todos los tenants
Cada fila tiene un campo tenant_id que identifica a qué cliente pertenece
Cómo se aísla la información:
A nivel de aplicación: todas las consultas filtran por tenant_id
A nivel de base de datos: se pueden usar políticas de Row-Level Security (RLS) para reforzar la seguridad
-- Ejemplo de tabla con tenant_idCREATETABLE users ( id SERIALPRIMARYKEY, tenant_id UUID NOTNULL, email VARCHAR(255)NOTNULL, name VARCHAR(255)NOTNULL, created_at TIMESTAMPDEFAULTCURRENT_TIMESTAMP);-- Índice para optimizar consultas por tenantCREATEINDEX idx_users_tenant_id ON users(tenant_id);-- Row Level Security (RLS) para garantizar aislamientoALTERTABLE users ENABLEROWLEVEL SECURITY;-- Política que solo permite ver datos del tenant actualCREATE POLICY tenant_isolation ON users
USING(tenant_id = current_setting('app.current_tenant_id')::UUID);
Ventajas
Muy eficiente: un solo pool de conexiones, un solo esquema que mantener
Menor coste operativo: menos instancias y menos backups que gestionar
Escalabilidad: más fácil añadir nuevos tenants
Desventajas
Riesgo mayor si hay un bug en las consultas: un fallo en el filtro tenant_id puede exponer datos de otro cliente
Migraciones de datos más complejas: un cambio de esquema afecta a todos los tenants a la vez
Ejemplos en la vida real
Slack: cada workspace es un tenant, pero los mensajes y usuarios viven en las mismas bases de datos distribuidas
Trello: múltiples tableros y equipos comparten infraestructura
2. Multitenancy con esquema dedicado
En este modelo:
Hay una sola instancia de base de datos física, pero cada tenant tiene su propio esquema dentro de la base
Ejemplo: en PostgreSQL, schema_tenant_1, schema_tenant_2, etc.
Modelo de Esquemas Dedicados
-- Creación de esquemas por tenantCREATESCHEMA tenant_company_a;CREATESCHEMA tenant_company_b;-- Tablas en esquema dedicadoCREATETABLE tenant_company_a.users ( id SERIALPRIMARYKEY, email VARCHAR(255)NOTNULL, name VARCHAR(255)NOTNULL, created_at TIMESTAMPDEFAULTCURRENT_TIMESTAMP);CREATETABLE tenant_company_b.users ( id SERIALPRIMARYKEY, email VARCHAR(255)NOTNULL, name VARCHAR(255)NOTNULL, created_at TIMESTAMPDEFAULTCURRENT_TIMESTAMP);
Ventajas
Mejor aislamiento que el modelo de un solo esquema
Migraciones más controladas: puedes probar un cambio de esquema en un tenant antes de aplicarlo a todos
Posible personalización de datos y estructuras para tenants específicos
Desventajas
Gestión más compleja: crear un esquema nuevo por tenant, mantener scripts de migración separados
Escalabilidad limitada si tienes miles de tenants (demasiados esquemas en una sola base)
Ejemplos
Aplicaciones B2B con pocos clientes de gran tamaño que necesitan personalizaciones específicas
Plataformas de ERP que alojan a empresas grandes con requisitos distintos
3. Multitenancy con base de datos dedicada
En este modelo:
Cada tenant tiene su propia base de datos
Puede ser incluso en un servidor distinto
Modelo de Bases de Datos Dedicadas
Ventajas
Aislamiento casi total de datos
Facilidad para cumplir requisitos de compliance (ISO, HIPAA, GDPR) que exigen separación física
Escalabilidad independiente: puedes asignar más recursos a un cliente que lo necesite
Desventajas
Coste mucho mayor: más instancias que mantener y monitorizar
Mantenimiento y despliegues más complejos: las migraciones hay que repetirlas en todas las bases
La automatización se vuelve obligatoria para manejar muchos tenants
Ejemplos
Sistemas bancarios que no pueden mezclar datos por regulación
Aplicaciones médicas que manejan historiales clínicos y requieren segregación estricta
Comparativa rápida
Modelo
Aislamiento
Coste
Escalabilidad
Complejidad
Lógico (campo tenant_id)
Bajo-Medio
Bajo
Alto
Baja
Esquema dedicado
Medio
Medio
Medio-Alto
Media
Base dedicada
Alto
Alto
Medio
Alta
Factores para elegir el modelo
Regulación y compliance: si tus clientes están en sectores con normas estrictas, el aislamiento físico puede ser obligatorio
Cantidad de tenants: para miles de clientes, el aislamiento lógico es más manejable
Necesidad de personalización: si un tenant requiere cambios grandes en la estructura de datos, mejor esquema o base dedicada
Presupuesto: bases dedicadas implican un coste operativo mucho más alto
Implementación práctica: Spring Boot con PostgreSQL
Veamos cómo implementar el modelo de aislamiento lógico con Spring Boot y PostgreSQL:
// Interceptor para establecer el contexto del tenant@Componentclass TenantInterceptor : HandlerInterceptor {overridefunpreHandle( request: HttpServletRequest, response: HttpServletResponse, handler: Any
): Boolean {val token =extractJwtToken(request)val tenantId =extractTenantFromToken(token)// Establecer tenant en el contexto de la aplicación TenantContext.setCurrentTenant(tenantId)returntrue}overridefunafterCompletion( request: HttpServletRequest, response: HttpServletResponse, handler: Any, ex: Exception?){// Limpiar contexto después de la request TenantContext.clear()}}
// Repository con filtro automático por tenant@Repositoryinterface UserRepository : JpaRepository<User, Long>{@Query("SELECT u FROM User u WHERE u.tenantId = :tenantId")funfindByTenantId(@Param("tenantId") tenantId: UUID): List<User>@Query("SELECT u FROM User u WHERE u.tenantId = :tenantId AND u.email = :email")funfindByTenantIdAndEmail(@Param("tenantId") tenantId: UUID,@Param("email") email: String
): User?}// Service que usa el contexto del tenant automáticamente@ServiceclassUserService(privateval userRepository: UserRepository){fungetCurrentTenantUsers(): List<User>{val currentTenantId = TenantContext.getCurrentTenant()return userRepository.findByTenantId(currentTenantId)}funcreateUser(email: String, name: String): User {val currentTenantId = TenantContext.getCurrentTenant()val user =User( tenantId = currentTenantId, email = email, name = name
)return userRepository.save(user)}}
Más ejemplos de empresas multitenant
Shopify: cada tienda es un tenant, datos aislados pero compartiendo backend y capas de infraestructura global
Netflix (en la capa de gestión de usuarios y cuentas): cada cuenta es un tenant con sus propios perfiles y datos de consumo
Atlassian (Jira, Confluence): instancias multitenant que alojan múltiples empresas, cada una con sus propios proyectos y configuraciones
Zoom: cada organización o cuenta empresarial es un tenant; las reuniones, usuarios y grabaciones se segmentan por account_id
Salesforce: pionero en SaaS multitenant, cada organización tiene su configuración personalizada pero comparte la misma infraestructura masiva
Buenas prácticas en multitenancy
Seguridad
Autenticación con contexto de tenant: incluir tenant_id en el token JWT
Validación doble: aplicar filtros en la aplicación y Row-Level Security en la base
Logging con tenant_id para auditoría y depuración rápida
Performance
Limitación de recursos por tenant: evitar que un cliente acapare CPU, memoria o ancho de banda
Índices optimizados por tenant_id en todas las tablas principales
Caching con claves que incluyan el tenant_id
Automatización
Scripts automatizados para el alta de nuevos tenants
Migraciones de base de datos automáticas y versionadas
Monitoreo por tenant para detectar problemas específicos
Observabilidad
Métricas segmentadas por tenant
Alertas configurables por cliente
Dashboards de uso y performance por tenant
Desafíos comunes y cómo resolverlos
Data Leakage (Filtración de datos)
El mayor riesgo: consultas que olvidan filtrar por tenant_id
Solución: Implementa Row-Level Security a nivel de base de datos como segunda línea de defensa, y tests automatizados que verifiquen el aislamiento.
Balanceamiento de carga por tenant
Algunos tenants pueden consumir más recursos que otros
Solución: Implementa throttling y rate limiting por tenant, y considera mover clientes pesados a infraestructura dedicada.
Migraciones complejas
Cambios de esquema que afectan a miles de tenants
Solución: Migraciones incrementales, feature flags por tenant, y estrategias de rollback granulares.
Arquitectura del Modelo de Aislamiento Lógico
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, requisitos de seguridad y 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.
Próximos pasos
En próximas entregas, profundizaré en cómo implementar un modelo multitenant lógico completo con Spring Boot, PostgreSQL y autenticación JWT, paso a paso, incluyendo:
Configuración de Row-Level Security en PostgreSQL
Implementación de interceptors y filtros automáticos
Estrategias de testing para aplicaciones multitenant
Monitoreo y observabilidad por tenant
¿Tienes experiencia implementando multitenancy? ¿Qué desafíos has encontrado? Me encantaría conocer tu perspectiva.