10 de agosto de 2026
Multi-tenant real vs. tenant_id: la diferencia que casi nadie explica
Cuando un cliente nos pide “un sistema que sirva para varias empresas”, casi siempre lo primero que
imagina es una tabla empresas y una columna empresa_id repetida en cada tabla del sistema. Es la
forma más rápida de construir algo que parece multi-tenant. También es, en la mayoría de los casos,
la forma equivocada de resolverlo — sobre todo cuando los datos son sensibles.
El problema del tenant_id
Filtrar por tenant_id funciona hasta que un solo WHERE se olvida en un query, un job en segundo
plano no recibe el contexto del tenant correcto, o un desarrollador nuevo escribe una consulta directa
para depurar algo en producción. En ese momento, los datos de una empresa cliente pueden aparecer
mezclados con los de otra. No es un bug improbable — es un patrón de error que ocurre una y otra vez
en sistemas grandes, precisamente porque el aislamiento depende de que cada query, en cada
capa del sistema, recuerde aplicar el filtro correcto.
Lo que hicimos distinto en nuestra plataforma de RRHH
Al construir nuestro sistema de RRHH, planillas y biométricos multi-empresa, decidimos que el
aislamiento entre empresas cliente no podía depender de que nadie se olvidara un WHERE. Usamos
stancl/tenancy sobre Laravel para que cada empresa cliente tenga su propia base de datos física.
No es una capa de abstracción encima de tablas compartidas — es una base de datos separada por completo.
Esto cambia la naturaleza del riesgo:
- Un error de código que olvida filtrar por tenant simplemente no puede tocar los datos de otra empresa, porque la conexión a la base de datos ya está resuelta al tenant correcto antes de que la consulta se ejecute.
- Un backup, una restauración o una migración de una empresa no afecta a las demás.
- Si algún día una empresa cliente necesita irse con sus datos, no hay que “extraerlos” de una tabla compartida — ya están en su propia base, lista para exportar.
El costo de hacerlo bien
Esto no es gratis. Migraciones, seeders y jobs en segundo plano tienen que ser conscientes de en qué
tenant están corriendo. El panel de super-administrador que da de alta una empresa nueva no solo crea
un registro — provisiona una base de datos completa. Es más trabajo de ingeniería que un tenant_id.
Pero cuando el sistema maneja remuneración, datos de salud (EsSalud/EPS/SIS) y marcaciones biométricas de varias empresas a la vez — como es el caso de nuestra plataforma de RRHH — ese trabajo extra no es opcional. Es la diferencia entre un sistema que promete aislamiento y uno que lo garantiza por diseño.
Cuándo sí basta con tenant_id
No siempre hace falta este nivel de aislamiento. Si los datos no son sensibles, si el volumen por
tenant es bajo, o si el producto es un MVP que necesita validarse rápido antes de invertir en
arquitectura, un tenant_id bien indexado es una decisión razonable — y la que usamos, por ejemplo,
en el Libro de Reclamaciones Multi-Hotel, donde el modelo de negocio es distinto y el riesgo
de mezclar datos entre hoteles es menor.
La pregunta que hacemos antes de decidir no es “¿cómo construimos multi-tenant?” sino qué pasa si falla el aislamiento — y diseñamos en función de esa respuesta, no de la que sea más rápida de programar.