07. VI. Procesos
Ejecuta la aplicación como uno o más procesos sin estado (“share-nothing”).
La regla
Los procesos de una aplicación twelve-factor no tienen estado y no comparten nada entre sí. Cualquier dato que necesite persistir entre solicitudes debe guardarse en un backing service con estado (Factor IV) — típicamente una base de datos.
Memoria y disco como caché transitorio, nunca como fuente de verdad
La memoria del proceso y el sistema de archivos local pueden usarse como caché de corta vida dentro de una única transacción (por ejemplo, para bajar un archivo grande a disco temporalmente mientras se procesa). Lo que no pueden hacer es asumirse disponibles en la siguiente solicitud, porque:
- Con múltiples procesos corriendo en paralelo, es probable que dos solicitudes sucesivas del mismo usuario las atienda un proceso distinto.
- Un despliegue nuevo (Factor V) o un cambio de configuración típicamente reinicia los procesos, destruyendo cualquier estado local acumulado.
El anti-patrón: sticky sessions
Las sticky sessions (o “session affinity”) intentan resolver esto en el balanceador de carga, forzando que todas las solicitudes de un mismo usuario vayan siempre al mismo proceso — que cachea sus datos de sesión en memoria.
El manifiesto es tajante: “las sticky sessions son una violación de twelve-factor y no deberían usarse nunca.”
El problema no es sólo de principios: las sticky sessions rompen el escalado horizontal simple (agregar/quitar procesos libremente) y hacen que un reinicio de proceso se sienta como una caída para ese subconjunto de usuarios.
La alternativa correcta
Cuando se necesita guardar datos de sesión con expiración, la solución es un servicio de datos con expiración, como Memcached o Redis/Valkey — un backing service (Factor IV) accesible desde cualquier proceso de la aplicación, no atado a uno en particular.
flowchart LR
LB["Balanceador"] --> P1["Proceso 1"]
LB --> P2["Proceso 2"]
LB --> P3["Proceso 3"]
P1 --> Store[("Redis / Valkey<br/>sesiones compartidas")]
P2 --> Store
P3 --> Store
Con este esquema, cualquier proceso puede atender cualquier solicitud, sin importar cuál la atendió antes.
Checklist del factor VI
- Ningún dato de negocio o de sesión de usuario se guarda únicamente en memoria del proceso o en disco local persistente.
- No hay sticky sessions configuradas en el balanceador de carga.
- Los datos que necesitan persistir entre solicitudes viven en un backing service compartido (DB, Redis/Valkey).
- Matar y levantar cualquier proceso en cualquier momento no pierde datos de negocio.
Con procesos sin estado resueltos, el siguiente factor explica cómo esos procesos se hacen accesibles hacia afuera: la asignación de puertos.