Volver al Blog
Arquitectura 15 min de lectura Deep Dive

Arquitectura Multi-Tenant: Cómo Cadences Escala

Un deep dive técnico en cómo servimos miles de organizaciones con aislamiento total de datos, latencia de milisegundos y costes que escalan linealmente.

GM
Gonzalo Monzón
Centro de datos y arquitectura de servidores moderna

Construir un SaaS para un cliente es relativamente sencillo. Construir uno que sirva a miles de organizaciones simultáneamente, con datos completamente aislados, rendimiento consistente y costes predecibles... eso es un desafío de arquitectura de otro nivel. En este artículo explicamos cómo lo hemos resuelto.

🏗️ Audiencia

Este artículo es técnico. Está pensado para CTOs, arquitectos de software y desarrolladores senior que quieran entender las decisiones de diseño detrás de Cadences. Si te gustan los diagramas de arquitectura y las discusiones sobre trade-offs, este es tu artículo.

El Dilema

Database per Tenant vs Shared Database

El primer gran dilema de cualquier arquitectura multi-tenant es cómo manejar los datos. Hay dos enfoques clásicos:

Shared Database

Todos los tenants en una sola base de datos con `tenant_id` en cada tabla.

  • + Más simple de mantener
  • + Migraciones unificadas
  • Riesgo de data leak
  • Noisy neighbor problem
  • Escalabilidad limitada

Database per Tenant

Cada organización tiene su propia base de datos completamente aislada.

  • + Aislamiento total de datos
  • + Sin noisy neighbor
  • + Backup/restore por tenant
  • Más infraestructura que gestionar
  • Migraciones coordinadas

Cadences eligió Database per Tenant. ¿La razón? Gracias a Cloudflare D1, el coste operativo de gestionar miles de bases de datos es prácticamente cero.

Stack Técnico

El Stack de Cadences

🌐

Edge Layer: Cloudflare Workers

275+ puntos de presencia globales. Código ejecuta en < 10ms desde el edge más cercano al usuario. Zero cold starts.

🧠

State Layer: Durable Objects

Estado mutable con consistencia fuerte. Cada organización tiene sus propios DOs para sesiones, rate limiting, WebSocket hubs y locks distribuidos.

🗄️

Data Layer: D1 (SQLite en el Edge)

Una base de datos D1 por organización. SQL completo, transacciones ACID, réplicas de lectura globales. Backups automáticos.

📦

Storage Layer: R2 + KV

R2 para archivos y media (compatible S3). KV para configuraciones, caché y feature flags. Ambos edge-native.

Tenant Resolution

Cómo se Resuelve el Tenant

Cuando una petición HTTP llega a Cadences, lo primero que ocurre es identificar a qué organización pertenece. Esto se hace en menos de 1ms:

Worker: Tenant Resolution
// 1. Extract org from JWT token
const token = request.headers.get('Authorization');
const { orgId } = await verifyJWT(token);

// 2. Resolve org's D1 database binding
const db = env[`DB_ORG_${orgId}`];

// 3. Route to org's Durable Object
const doId = env.ORG_STATE.idFromName(orgId);
const orgState = env.ORG_STATE.get(doId);

// 4. Execute query on org's isolated database
const contacts = await db
  .prepare("SELECT * FROM contacts WHERE active = 1")
  .all();

// No `WHERE org_id = ?` needed → the entire DB is this org's

Observa la última línea: no hay WHERE org_id = ?. No hace falta. Toda la base de datos pertenece a esa organización. Es imposible acceder accidentalmente a datos de otro tenant.

Seguridad

Garantías de Aislamiento

🔒

Data Isolation

Cada org tiene su propia D1 database. No hay posibilidad física de cross-tenant data access.

Compute Isolation

Workers ejecutan en V8 isolates. Cada request corre en su propio contexto aislado con limits de CPU/memoria.

📁

Storage Isolation

Archivos en R2 bajo prefix por org. KV namespaces con org-scoped keys. Sin posibilidad de colisión.

🔑

Auth Isolation

JWT tokens firmados por org con HMAC-SHA256. Un token de org A no funciona contra org B, nunca.

Operations

Migraciones Coordinadas

El mayor reto operativo de database-per-tenant es ejecutar migraciones de esquema en miles de bases de datos. Nuestro enfoque:

1

Versionado de esquema

Cada D1 tiene una tabla _migrations que trackea qué versión de esquema tiene. Similar a Flyway/Liquibase, pero en SQLite.

2

Lazy migration

Las migraciones se aplican on-demand cuando un tenant hace su primera request tras un deploy. Esto distribuye la carga en lugar de ejecutar 5.000 migraciones a la vez.

3

Batch migration worker

Un worker programado (cron) recorre las orgs que llevan más de 24h sin migrar y aplica las migraciones pendientes en background.

4

Safe migrations only

Solo se permiten migraciones backward-compatible: ADD COLUMN sí, DROP COLUMN nunca en el mismo deploy. Breaking changes se hacen en 2 fases.

Economía

Modelo de Costes Edge-Native

Una de las preguntas más frecuentes es: "¿No es carísimo tener una database por tenant?" La respuesta corta: no, con Cloudflare D1 es más barato que la alternativa centralizada.

Componente Modelo de coste Coste típico / org
D1 Database $0.75/M reads, $1/M writes ~$0.05/mes (org típica)
Workers $0.30/M requests ~$0.02/mes
Durable Objects $0.15/M requests + storage ~$0.01/mes
R2 Storage $0.015/GB/mes ~$0.03/mes (2GB media)
KV $0.50/M reads ~$0.01/mes
Total por organización ~$0.12/mes

$0.12 por organización al mes para infraestructura completa. Compara eso con una instancia RDS en AWS ($50+/mes) o un cluster de PostgreSQL para multi-tenancy ($200+/mes). El edge-native approach no solo es más rápido — es órdenes de magnitud más barato.

Comparativa

Edge-Native vs Traditional Cloud

Aspecto AWS/GCP Traditional Cadences (Edge-Native)
Cold start 100ms - 10s (Lambda) 0ms (V8 isolates)
Latencia global 50-300ms (región central) 5-20ms (edge local)
Escalado Auto-scaling con lag Instantáneo (por request)
Coste mínimo $50-200/mes base $5/mes (Workers Paid)
DevOps requerido Alto (VPC, IAM, monitoring) Mínimo (wrangler deploy)
Lecciones

Lo que Hemos Aprendido

1. SQLite en el edge es sorprendentemente potente

D1 soporta CTEs, window functions, JSON functions, FTS5 full-text search. Para el 95% de las consultas SaaS, es más que suficiente.

2. Durable Objects resuelven problemas que parecían imposibles

Rate limiting por org, WebSocket hubs, distributed locks, session management — todo con consistencia fuerte y sin Redis.

3. La mayor complejidad está en las migraciones

El lazy migration pattern fue crítico. Sin él, cada deploy sería un cuello de botella. Con él, las migraciones son transparentes.

4. Monitorización distribuida requiere su propio tooling

Con miles de D1 databases no puedes usar pgAdmin. Construimos un dashboard interno (Heartbeat Studio) que muestra health, tamaño y queries lentas de cada org.

¿Quieres construir sobre esta arquitectura?

Si estás evaluando arquitecturas multi-tenant para tu SaaS, podemos ayudarte. Ofrecemos consultoría de arquitectura edge-native basada en nuestra experiencia real con Cadences.

Hablar con el Equipo
Reflexión Final

Conclusión

La arquitectura multi-tenant de Cadences demuestra que database-per-tenant no tiene por qué ser caro ni complejo. Con el stack correcto (D1, Workers, Durable Objects), obtienes aislamiento total, rendimiento global y costes que escalan linealmente con el número de clientes.

El edge-native approach no es solo una optimización de rendimiento — es un cambio fundamental en la economía del SaaS. Cuando tu infraestructura cuesta $0.12 por tenant al mes, las decisiones de negocio cambian radicalmente.

El edge no es el futuro. Es el presente. Y es sorprendentemente barato.

GM
Gonzalo Monzón
Principal Solutions Architect, Cadences Lab
Compartir: