Multi-tenant SaaS: aislamiento real — 3 patrones y cuándo cada uno se vuelve pesadilla
Pool, schema-per-tenant, app-per-tenant. Cada patrón tiene beneficios obvios y costos invisibles. Cómo decidir antes del primer cliente B2B serio preguntando 'mis datos están aislados?'.
La primera pregunta de un comprador B2B serio, después de que el producto pasa por la demo y antes de que el jurídico entre a la sala, es siempre la misma: "¿mis datos están aislados de los otros clientes?". Si tu respuesta es "ah, filtramos por tenant_id en cada query", el contrato acaba de volverse humo. El comprador no está pidiendo una justificación técnica — está pidiendo una garantía que sobreviva a una auditoría, a un incidente, y a una rotación de dev júnior.
Existen tres patrones reales de aislamiento multi-tenant en SaaS B2B. Cada uno tiene beneficios obvios en la presentación y costos invisibles en la operación. Este post mapea los tres, muestra exactamente cuándo cada uno se vuelve pesadilla, y explica el viaje típico de una startup brasileña que empieza con cincuenta clientes pequeños y termina atendiendo a un banco regulado.
Por qué eso importa ahora — no el año que viene
Multi-tenancy es una decisión arquitectural que parece postergable hasta el exacto momento en que deja de serlo. Cuatro fuerzas están empujando esa decisión al frente del roadmap de las startups B2B brasileñas en 2026:
LGPD se volvió exigencia práctica, no solo legal. La ley está en vigor desde 2020, pero los DPOs corporativos empezaron a pedir evidencia operacional solo en los últimos dos años. La pregunta dejó de ser "¿están en conformidad?" y se volvió "¿cómo demuestran tratamiento adecuado de datos personales?". Demostración exige separación visible, log de acceso, y proceso claro de exclusión. Pool puro vuelve todo eso más difícil — no imposible, pero más difícil de justificar a un auditor que nunca vio tu arquitectura.
Cliente B2B grande exige aislamiento como prerrequisito de contrato. Ese es el punto del párrafo de apertura. Si tu pipeline tiene una propuesta de R$ 50 mil al mes con una operación de logística regional, es prácticamente seguro que el departamento de seguridad de la información de ellos va a mandar un cuestionario de ciento ochenta preguntas. Casi la mitad de las preguntas es sobre aislamiento. Responder "compartimos una base con filtros lógicos" entrega la cuenta al competidor que respondió "schema dedicado por cliente" — aunque la diferencia real, en términos de riesgo, sea pequeña.
Compliance sectorial puede exigir aislamiento físico. Salud (LGPD + CFM), financiero (Bacen, CVM), educación básica privada (LGPD + ECA), seguros (SUSEP). Sectores regulados ocasionalmente listan "segregación de datos por cliente en capa física" como control exigido. Cuando eso aparece, schema-per-tenant resuelve con algún esfuerzo; pool no resuelve.
Un cliente va a volverse diez veces mayor que los otros. La distribución de uso en SaaS B2B sigue ley de potencia. Tu mayor cliente va a consumir más recursos que los cincuenta menores sumados. En el pool puro, ese cliente degrada la experiencia de todos los demás — y no logras cobrar más por eso sin un modelo de cobranza que precise uso, lo que nadie quiere construir antes de lo necesario.
Y la quinta fuerza, tal vez la más importante: migrar de un patrón a otro después de tener clientes en producción es proyecto de meses, no de días. Vas a elegir mal en algún eje — todo el mundo elige — pero elegir conscientemente hace la diferencia entre "refactorización de seis semanas" y "reescritura de seis meses".
Patrón 1 — Pool (comparte todo)
Setup más simple posible. Una base de datos, una instancia de la aplicación, una stack de infraestructura. Todos los clientes viven en las mismas tablas. Cada query de la aplicación tiene un filtro adicional WHERE tenant_id = ? inyectado por un middleware antes de llegar a la base. Postgres Row-Level Security (RLS) refuerza ese filtro en el nivel de la base — una segunda capa que dispara incluso si el middleware de la aplicación olvida.
Onboarding de nuevo cliente es literalmente un INSERT en la tabla tenants. Treinta milisegundos después el cliente ya tiene ambiente funcional. El costo marginal de agregar tenant es prácticamente cero — solo estás usando más líneas en la misma base, más bytes en el mismo cache.
Puntos fuertes del pool:
- Costo operacional bajo. Una base para hacer backup, una stack para monitorear, una versión de aplicación corriendo.
- Onboarding instantáneo. Flujo de signup con tarjeta de crédito es trivial.
- Escala sublineal. Mil clientes no cuestan mil veces más que uno.
- Cross-tenant analytics son naturales. Dashboard interno de "cuántos usuarios activos en el mes" es un
SELECT COUNT(*)sin gimnasia. - Migrations son simples. Un
ALTER TABLEaplica para todos los clientes al mismo tiempo.
Puntos débiles del pool:
- Bug de SQL es incidente crítico. Un
WHEREolvidado, unJOINque filtra a otro contexto, una migration mal escrita — y datos del cliente A aparecen en la pantalla del cliente B. Ese incidente ya mató empresas (literalmente: contratos cancelados en masa, pérdida de confianza irreversible). RLS en Postgres es el cinturón de seguridad que reduce drásticamente ese riesgo, pero exige disciplina para configurar bien y probar todas las roles. - Vecino ruidoso. Un cliente que dispara un reporte pesado a las catorce horas del martes consume el pool de conexiones y degrada la latencia de todos los demás. Puedes agregar límites de query por tenant, pero eso es trabajo adicional.
- Backup es todo-o-nada. Restaurar un cliente específico después de una operación destructiva exige snapshot de la base entera, restore en ambiente paralelo, y export-import selectivo. Operación pesada de una a cuatro horas.
- Compliance que exige separación física no atiende. Si el cliente pregunta "¿dónde físicamente moran mis datos?", la respuesta es "en el mismo archivo de datos que los de todos los demás clientes" — verdad que aleja perfiles específicos.
- Customización se vuelve columna nullable. Cliente Y necesita un campo extra. Lo agregas. Otro cliente no usa ese campo. En seis meses nadie recuerda para qué sirve aquella columna
extra_data_3. Esa acumulación es uno de los síntomas más previsibles del pool maduro.
Cuándo el pool tiene sentido: SaaS B2B SMB (clientes pequeños y medianos), tenants relativamente similares en uso, bajo riesgo regulatorio, equipo de ingeniería pequeño (tres a ocho personas), producto todavía buscando product-market fit. Prácticamente todo SaaS empieza aquí — y está correcto. El error no es empezar con pool; es no saber cuándo salir.
Patrón 2 — Schema-per-tenant (base compartida, schemas separados)
Medio término arquitectural. Todavía tienes una instancia de base — una instancia de Postgres corriendo, con sus parámetros, conexiones, replicación. Pero dentro de ella, cada cliente tiene su propio schema. Postgres llama de schema; MySQL llama de database; el concepto es el mismo: namespace nombrado dentro del servidor, con tablas propias, índices propios, y privilegios propios.
La aplicación selecciona el schema correcto vía SET search_path TO tenant_acme (o equivalente) al inicio de cada conexión, basado en qué tenant está haciendo la request. Las tablas existen con la misma estructura en todos los schemas, pero son físicamente separadas: schema tenant_acme tiene sus propias filas de users, tenant_xyz tiene las suyas, y queries dentro de un schema no ven el otro sin privilegio explícito.
Puntos fuertes del schema-per-tenant:
- Aislamiento de datos fuerte por default. Sin
WHERE tenant_iden ningún lugar — las tablas están físicamente separadas. Bug de SQL queda circunscrito al schema actual. - Backup por tenant es práctico.
pg_dump --schema=tenant_acmeexporta solo aquel cliente. Restaurar es lo mismo: subir en un ambiente paralelo, importar el schema, y mover datos específicos. - Cuotas de recurso por schema. Postgres permite limitar conexiones por role, y roles pueden estar atadas a schemas. Puedes garantizar que tenant grande no consume todas las conexiones de la base.
- Customización limpia. ¿Cliente Y necesita un campo extra? Agrégalo en el schema de él solamente. Otros clientes ni saben que aquel campo existe. El esquema base sigue limpio.
- Demostración de separación queda obvia para auditoría. "Cada cliente tiene su propio namespace de base con privilegios aislados" es respuesta que satisface la mayor parte de los cuestionarios de seguridad.
Puntos débiles del schema-per-tenant:
- Migrations multiplican por N. Una migration de diez minutos con mil schemas se vuelve ciento sesenta horas de trabajo de base si corre en serie. Necesitas paralelismo cuidadoso, scripts de migration que conocen el conjunto de schemas, y ventana de mantenimiento planeada — o estrategia de migrations sin bloqueo que funcione esquema-a-esquema.
- Pool de conexiones queda complicado. Si cada conexión necesita
SET search_pathpor tenant, el pgBouncer simple no funciona — él reusa conexiones entre clientes diferentes. Soluciones: pool por schema (rompe cardinalidad), session-mode pooling (más lento), o middleware de la aplicación que gestiona el reset. - Cross-tenant analytics se vuelven caros. Para responder "¿cuántos usuarios activos tengo en todos los clientes?" necesitas unionar mil tablas. Solución real: ETL diario para un warehouse separado (ClickHouse, BigQuery), con
tenant_iddesnormalizado. - Bug en código de switching todavía es riesgo. Si el middleware selecciona el schema equivocado por bug de session leakage entre requests, tienes el mismo tipo de filtración que el pool tiene. Menos común, pero posible.
- Límite práctico de schemas. Postgres aguanta decenas de miles de schemas, pero el catálogo de la base queda pesado en algún punto — listados lentos, autovacuum compitiendo. Empresas que corren más de cinco mil schemas en una instancia única reportan dolor.
Cuándo el schema-per-tenant tiene sentido: SaaS B2B mid-market, diez a mil clientes, algunos clientes de alto valor que justifican customización, compliance moderada. Es el patrón "intermedio" en el sentido literal — cambias un poco de la simplicidad operacional del pool por un aislamiento más fuerte y por flexibilidad de customización.
Patrón 3 — App-per-tenant (silo completo)
Cada cliente recibe instancia dedicada de todo: aplicación, base, cache, cola de jobs, agendador. Lo que comparten es solo la infraestructura física — el cluster de máquinas donde los contenedores corren. Pero cada workload tiene su propia base con sus propios datos, su propia URL (acme.app.com, cliente-xyz.app.com), y potencialmente su propia versión de la aplicación.
Implementación seria de ese patrón exige orquestador. Sin orquestación, provisionar un nuevo cliente significa crear manualmente máquina virtual, correr setup de base, deploy de la aplicación, configurar DNS, emitir certificado TLS — operación de horas que nadie va a aguantar repetir veinte veces al mes. Con orquestador, eso es un job parametrizado: disparas una definición que dice "nuevo tenant acme, plan enterprise, base aislada, certificado automático", el cluster aloca, configura, y dispara en uno a tres minutos.
Kubernetes hace eso con namespaces y Helm. HeroCtl hace con job templates. Otros orquestadores hacen con primitivas propias. Lo que importa es que el tiempo de onboarding de un nuevo cliente en esa arquitectura — minutos, no segundos como en el pool — no se vuelva dolor humano porque está automatizado.
Puntos fuertes del app-per-tenant:
- Aislamiento máximo. No hay código compartido consultando datos de más de un cliente — físicamente imposible. Bug de SQL afecta solo al cliente de aquella instancia.
- Customización total. Cliente A puede correr versión
2.4de la aplicación, cliente B versión2.5. Útil para pruebas graduales de release, o para atender a clientes que pidieron un patch específico. - Falla aislada. Si la base del cliente A se corrompió, cliente B ni percibe. Cliente A tiene outage; cliente B no tiene.
- Compliance pesada se vuelve viable. FedRAMP, HIPAA con requisitos multi-tenant rígidos, contratos con cláusula de "infraestructura dedicada" — todos pasan.
- Deploys regionales por cliente. ¿Cliente brasileño con exigencia de datos en territorio nacional? Corre en el datacenter de São Paulo. ¿Cliente europeo? Frankfurt. La primitiva de "correr tenant donde necesita estar" pasa a existir.
Puntos débiles del app-per-tenant:
- Costo escala lineal. Mil clientes pequeños cuestan aproximadamente mil veces más que un cliente. Sin ganancia de pool. Para clientes de bajo ticket, el margen desaparece.
- Onboarding lleva minutos, no segundos. Puede ser inaceptable para modelos self-service con signup por tarjeta de crédito. Funciona para modelos de venta asistida donde el onboarding es proceso, no flujo de compra.
- Operación multiplica por N. Cada base necesita backup, cada aplicación necesita monitoreo, cada deploy necesita validación. Sin herramientas de orquestación centralizada, se vuelve inviable en dos decenas de clientes.
- Cross-tenant analytics son caros. Peor que schema-per-tenant — tienes que sincronizar datos de bases completamente separadas. ETL para warehouse común es aún más necesario.
- Costo de infraestructura mínimo por tenant. Cada Postgres dedicado tiene overhead de doscientos a quinientos megabytes de RAM aun ocioso. Cada aplicación Go o Node más cien a doscientos megabytes. El piso de gasto es real.
Cuándo el app-per-tenant tiene sentido: SaaS enterprise, ARR alto por cliente (R$ 10 mil/mes por cliente para arriba es referencia confortable), compliance exigente, customización cliente es diferencial competitivo. Funciona también en contextos de cincuenta a mil clientes donde el ticket promedio sostiene el costo. Empresas que venden self-service en Stripe y cobran R$ 99/mes por usuario no caben aquí — la economía no cierra.
Tabla comparativa
| Criterio | Pool | Schema-per-tenant | App-per-tenant |
|---|---|---|---|
| Costo por tenant | Sublineal (casi cero adicional) | Casi lineal (overhead pequeño) | Lineal (instancia dedicada) |
| Tiempo de onboarding | Segundos (INSERT) | Segundos a minutos (CREATE SCHEMA + migrate) | Minutos (provisionar pila) |
| Performance overhead | Ninguno (comparte cache, etc) | Pequeño (más relations en el catálogo) | Alto (overhead por instancia) |
| Riesgo de leak por bug | Alto (mitigado por RLS) | Medio (mitigado por search_path) | Prácticamente nulo |
| Backup por tenant | Difícil (snapshot completo) | Fácil (pg_dump --schema) | Trivial (backup dedicado) |
| Customización cliente | Cara (columnas nullable) | Buena (campos extras en el schema) | Total (versión propia de la app) |
| Compliance enterprise | Difícil de demostrar | Demostrable | Fuerte por construcción |
| Rango de tenants ideal | 1 a 10 mil | 10 a 5 mil | 10 a 1.000 |
| Cross-tenant analytics | Trivial (una query) | Pesado (UNION N tablas o ETL) | Pesado (ETL obligatorio) |
| Equipo mínimo para operar | 2 a 5 devs | 4 a 10 devs con infra básica | 4 a 10 devs con orquestador |
Los límites superiores de rango de tenants son aproximados — empresas excedieron todos ellos con esfuerzo. Los números sirven como referencia de cuándo empieza a doler.
El viaje típico de SaaS brasileño
La mayoría de los SaaS B2B brasileños sigue un camino previsible, y entender el camino ayuda a elegir la etapa actual sin subdimensionar ni superdimensionar.
Etapa 1: cero a cincuenta clientes. Pool es la elección obvia. Equipo pequeño, costo bajo, nadie pidió compliance todavía, todos los clientes son parecidos en uso. Enfócate en product-market fit — cualquier hora gastada con aislamiento ahora es hora robada al producto. RLS en Postgres desde el día uno es la inversión mínima de defensa.
Etapa 2: cincuenta a quinientos clientes, primer cliente B2B mid-market llega. Aquí empieza a apretar. Aquel cliente con ciento cincuenta usuarios consume seis veces más recursos que los demás. El cuestionario de seguridad llega con la pregunta sobre aislamiento. Evaluar schema-per-tenant queda racional. Híbrido también es opción: pool para los pequeños, schema dedicado para los mayores que pidieron explícitamente. Migración en esa etapa es menos dolorosa porque la base todavía es manejable.
Etapa 3: quinientos clientes o primer cliente enterprise. Ahora la decisión es estructural. ¿Schema-per-tenant para todos? ¿App-per-tenant para los enterprise y schema para el resto? ¿Híbrido con tres capas (pool en los free, schema en los pagados, app en los enterprise)? La respuesta depende del mix de clientes — empresas con pocos clientes muy grandes tienden a app-per-tenant; empresas con mil clientes medianos quedan en schema-per-tenant.
Etapa 4: enterprise mode. App-per-tenant para los high-value, con schema-per-tenant o pool sosteniendo a los menores. Ese es el estado de empresas como Salesforce (que históricamente hizo schema-per-tenant en escala extrema), Notion (pool altamente optimizado), y herramientas enterprise más nuevas que adoptan app-per-tenant desde el nacimiento.
La transición entre etapas es donde mora la ingeniería más cara de la carrera de un SaaS. Quien ya pasó por eso conoce el olor.
Cómo HeroCtl ayuda en la etapa 3 y 4
El modelo app-per-tenant exige un orquestador competente. No es negociable: sin provisioning automatizado, la complejidad operacional inviabiliza el modelo. Cuatro primitivas que un orquestador necesita entregar para que app-per-tenant funcione, y cómo HeroCtl resuelve cada una:
Job templates parametrizados. Describes "tenant" una vez — qué aplicación corre, qué base, qué ingress, qué variables de ambiente, qué cuota de CPU y memoria. Para cada cliente nuevo, solo varías los parámetros (nombre, subdominio, plan). En HeroCtl, eso es un job spec corto con placeholders de variables.
API de onboarding. POST /v1/jobs con las variables del nuevo cliente. En segundos a pocos minutos, el cluster provisiona contenedores, sube la base, registra en el router interno, emite certificado TLS automático para acme.app.com. Sin operación manual.
Ruteo integrado por subdominio. Cada tenant gana un subdominio propio con TLS automático. El router interno del orquestador resuelve acme.app.com al contenedor correcto sin que configures DNS por cliente — wildcard de DNS apunta al cluster, y el orquestador hace el resto.
Cuotas y auditoría por tenant. Cada job carga límites de recurso (CPU, RAM, disco). Cliente que intente consumir más de lo que el plan permite, satura en su propio límite y no afecta a los vecinos. En el plan Business, log detallado de quién deployó qué versión de qué tenant, cuándo — útil para auditoría interna y para responder cuestionarios de cliente.
El cluster público de HeroCtl corre hoy en cuatro servidores totalizando cinco vCPUs y diez gigabytes de RAM, sosteniendo múltiples sitios con TLS automático. Cuando un nodo coordinador cae, el cluster elige otro coordinador en cerca de siete segundos — ventana corta lo suficiente para que clientes no perciban, y detalle operacional importante para quien opera app-per-tenant en producción. No estamos prometiendo magia: estamos describiendo lo que ya corre.
Cinco errores caros en multi-tenant
Errores que aparecen con frecuencia suficiente para valer un aviso explícito.
Compartir schema desde el día uno sin RLS. Pool sin Row-Level Security es apenas una capa de defensa: el middleware de la aplicación. Una capa falla en algún momento. RLS es la segunda capa — barata de configurar, y diferencia entre incidente vergonzoso e incidente fatal. Configura desde el inicio, aunque el equipo lo encuentre exagerado.
Migrar muy tarde de pool a schema. Empresa que creció a diez mil clientes en pool y descubre que necesita migrar a schema-per-tenant tiene un proyecto de cuatro a ocho meses por delante. Reescritura del middleware, migración de datos en ventanas, validación por cliente. Quien migró en quinientos tenants gastó tres semanas; quien migró en diez mil gastó un trimestre.
Customización ad-hoc en el pool. Cliente Y pide un campo extra. Lo agregas como columna nullable. En tres meses otros clientes pidieron otras tres columnas. En seis meses nadie entiende más la tabla. Lo que parecía atajo se vuelve deuda que paga intereses cada sprint. Resiste a ese patrón; o acepta que necesitas schema-per-tenant para atender a esas customizaciones limpiamente.
Backup solo de la base principal. Cuando sales del pool, backup necesita ser repensado. Schema separado necesita backup separado consciente. App-per-tenant necesita backup por base. Olvidar eso y descubrir en un incidente es catastrófico — empresas perdieron datos de cliente único porque el backup global no cubría las bases por tenant.
Cross-tenant analytics en el schema-per-tenant vía UNION. Funciona en diez clientes, queda pesado en cien, se vuelve inviable en mil. Construye ETL para warehouse separado desde temprano — ClickHouse o BigQuery con tenant_id desnormalizado es la solución estándar. Intentar mantener todo en el transaccional es receta de query de cuarenta minutos.
LGPD y multi-tenancy
LGPD no obliga modelo arquitectural específico, pero obliga demostración de tratamiento adecuado. Cada patrón tiene implicaciones diferentes.
Pool: necesitas demostrar separación lógica robusta (RLS configurado, probado, auditado), log de acceso a datos personales (quién leyó qué, cuándo), y proceso de exclusión que cubre todas las tablas relevantes para el derecho al olvido (artículo 18). Todo viable, pero con más trabajo de demostración.
Schema-per-tenant: demostración queda más simple. "Cada cliente tiene su schema aislado, con privilegios propios, y exclusión de datos es DROP SCHEMA" — frase que satisface al auditor sin dolor. Derecho al olvido es prácticamente trivial en ese modelo.
App-per-tenant: separación física es demostrable de forma directa. Auditoría queda más simple aún. Derecho al olvido es el destruir de la base del cliente.
En todos los modelos: log de acceso a datos personales (artículo 16, requisito de almacenamiento) es responsabilidad de la capa de aplicación — independe del modelo de aislamiento. Construye ese log desde temprano.
FAQ
¿Postgres RLS es confiable en producción? Sí, y ampliamente usado. Las trampas son dos: garantizar que todas las roles que conectan a la base sean no privilegiadas (super-user ignora RLS), y probar políticas con pruebas automatizadas que corren en CI. Quien configura RLS una vez y no prueba, descubre agujeros después.
¿Cómo automatizar migrations en schema-per-tenant?
Patrón común: tabla tenant_metadata con lista de schemas y versión actual de cada uno. Job de migration consulta, aplica en paralelo (con límite de concurrencia para no saturar la base), actualiza versión. Herramientas como Flyway y migrate con wrapper customizado funcionan. Reserva ventana de mantenimiento para migrations grandes incluso con paralelismo.
¿App-per-tenant no se vuelve demasiado caro para escalar? Se vuelve, si el ticket promedio es bajo. La regla práctica: ARR de R$ 10 mil/mes por cliente sostiene confortablemente el costo de infra dedicada. Por debajo de eso, el margen aprieta. Para clientes pequeños, mantén pool o schema. App-per-tenant es arma para clientes que pagan por la exclusividad.
¿Puedo mezclar modelos (high-value app-per-tenant, resto pool)? Sí, y híbrido es el estado final más común en SaaS maduro. La complejidad operacional aumenta — operas dos arquitecturas, no una — pero la economía compensa cuando los clientes high-value justifican el esfuerzo. Exige equipo con madurez de al menos seis a diez ingenieros.
¿tenant_id en el path o subdominio?
Subdominio (acme.app.com) suele ser mejor para branding y para cookies aisladas. Path (app.com/acme) es más simple en DNS y ruteo. Subdominio combina mejor con app-per-tenant; path combina bien con pool. Elige temprano, porque cambiar después rompe integraciones de cliente.
¿Encryption per tenant es viable? En pool, clave por tenant en la capa de aplicación es el camino — overhead razonable, y quedas con claves derivadas de una clave maestra protegida. En schema-per-tenant, misma estrategia. En app-per-tenant, encryption-at-rest de la base ya da aislamiento natural. Encryption per tenant es caro y raramente exigido — solo ve para allá si el cliente lo pide explícitamente en contrato.
¿Cuánto tiempo lleva onboarding en cada modelo? Pool: treinta a doscientos milisegundos (una transacción en la base). Schema-per-tenant: dos a treinta segundos (CREATE SCHEMA + migrations). App-per-tenant: treinta segundos a tres minutos (provisionar instancias, subir base, registrar TLS). Ese tiempo entra en el flujo de UX de signup — modelos self-service de tarjeta de crédito no soportan tiempo de minutos sin alguna forma de cola o notificación asíncrona.
Cierre
La elección de patrón multi-tenant no es técnicamente difícil — es organizacionalmente difícil. Difícil porque exige anticipar tres a cinco años de crecimiento de producto y clientela, y casi nadie anticipa bien. La defensa no es elegir perfecto; es elegir conscientemente, con trilla de migración mapeada para la próxima etapa, e instrumentación que avise cuando el modelo actual está pidiendo jubilación.
Pool es correcto al inicio. Schema-per-tenant es correcto en la transición a mid-market. App-per-tenant es correcto cuando el cliente paga por la exclusividad o cuando el compliance lo exige. Híbrido es el destino común.
Si estás construyendo SaaS B2B brasileño en 2026 y el producto está llegando a la etapa en que multi-tenancy importa, vale la pena conocer un orquestador que vuelve app-per-tenant operacionalmente accesible para equipos pequeños:
curl -sSL get.heroctl.com/install.sh | sh
Cuatro servidores, cinco vCPUs, diez gigabytes de RAM — el cluster público de demostración corre en recursos que caben en cualquier plan de cloud regional. Elección de coordinador en cerca de siete segundos cuando algo cae. Ruteo y TLS embebidos. Es la fundación que falta para mucha arquitectura de tenant aislado en equipo pequeño.
Para más sobre infra de SaaS, ve Postgres en producción: gestionado vs self-hosted y Cuánto cuesta alojar un SaaS en 2026.