Un ingeniero revisa una consola con una base de datos Postgres y diagramas de procesos en una oficina moderna.
Volver al blog

Postgres para workflows durables

Postgres para workflows durables puede simplificar tu backend si trabajas en un equipo pequeño o mediano. Te explicamos cuándo sirve, qué trade-offs tiene y cómo reemplazar colas y orquestadores sin sobrediseñar la arquitectura.

Si tienes un backend pequeño o mediano, seguro ya conoces este problema: una parte de tu sistema necesita hacer trabajo confiable en segundo plano, reintentar si falla, no duplicar acciones y sobrevivir a reinicios. En ese punto, muchas arquitecturas se llenan de piezas: una cola para encolar jobs, un worker pool para procesarlos, un orquestador para coordinar pasos, otra tabla para auditoría y, a veces, un sistema de estado aparte para saber en qué va cada ejecución.

La idea de usar Postgres como base para workflows durables parte de una pregunta bastante práctica: ¿y si no necesitas sumar más infraestructura para resolver eso? Si tu equipo ya depende de Postgres para casi todo, quizá puedas guardar el estado del workflow, coordinar transiciones y asegurar idempotencia sin introducir una cola externa o un orquestador pesado desde el día uno.

Qué significa realmente un workflow durable

Un workflow durable no es solo “un job que corre en background”. Hablamos de una secuencia de pasos que debe poder pausar, reanudarse, reintentarse y seguir siendo consistente aunque el proceso se caiga, el servidor se reinicie o un paso tarde más de lo normal. En otras palabras, el sistema no debería depender de que una instancia viva todo el tiempo para recordar lo que iba haciendo.

Esto importa porque muchos flujos de negocio no son triviales. Piensa en un cobro que debe validar saldo, registrar la transacción, enviar un correo y luego actualizar inventario. Si falla el envío del correo, no quieres repetir el cobro. Si se cae el worker después de registrar la transacción, no quieres perder el progreso. Y si el usuario vuelve a intentar la operación, tampoco quieres duplicar resultados.

Lo que suele romperse primero

Los fallos típicos no son espectaculares. Son los que pasan en producción un martes cualquiera:

  1. El worker termina a la mitad de un paso por un deploy.
  2. El mensaje se procesa dos veces porque hubo un retry sin idempotencia.
  3. La cola dice que el job fue entregado, pero el proceso nunca guardó su avance.
  4. Un orquestador externo añade latencia y complejidad para un flujo que solo tenía 4 pasos.

Cuando eso pasa, el problema no es solo técnico. También es operativo. Tienes más dashboards, más alertas, más estados intermedios y más lugares donde buscar qué salió mal.

Por qué Postgres encaja mejor de lo que parece

Postgres no es solo una base relacional para guardar usuarios y pedidos. También te da transacciones, locks, constraints, índices, JSONB, triggers y una semántica de consistencia que sirve muchísimo para coordinar trabajo durable. Si tu flujo necesita que un cambio de estado y una acción asociada queden atados, la transacción de Postgres es una herramienta bastante sólida.

La propuesta no es usar la base como si fuera una cola genérica para todo. La propuesta es más específica: si tu workflow está estrechamente ligado a datos que ya viven en Postgres, puedes usar la misma base para persistir estado, coordinar ejecución y guardar intentos. Eso reduce la cantidad de sistemas que tienes que operar.

La documentación oficial de Postgres sobre transacciones y bloqueo te da la base conceptual para este enfoque. Puedes revisar la guía oficial de transaction isolation y la referencia de SELECT … FOR UPDATE para entender cómo se protege el acceso concurrente.

La ventaja real: menos piezas, menos fallos

En equipos pequeños y medianos, el costo de operar una cola más un orquestador más una base de datos no siempre se justifica. No es solo el costo en infraestructura. También cuentas el tiempo de aprendizaje, el tiempo de debugging y el tiempo que pierdes cuando una pieza tiene un comportamiento raro bajo carga.

Con Postgres como centro del workflow, puedes tener:

  • una sola fuente de verdad para el estado,
  • transacciones para cambios atómicos,
  • reintentos controlados desde la aplicación,
  • y observabilidad directa con consultas SQL.

Si tu equipo ya sabe SQL, eso baja bastante la fricción. No necesitas que todos dominen una DSL nueva o entiendan cómo funciona un scheduler distribuido solo para mover cuatro estados.

Cómo se ve una implementación práctica

La forma más simple de pensar esto es como una tabla de workflows y otra de pasos o eventos. Cada workflow tiene un estado, un payload, un contador de reintentos y marcas de tiempo. Cada paso puede registrar si empezó, si terminó, si falló y con qué error.

Un patrón común es este:

  • crear el workflow dentro de una transacción,
  • dejarlo en estado pending,
  • tomarlo para ejecución con un lock o con una actualización condicional,
  • ejecutar el paso fuera de la transacción si hace trabajo externo,
  • y luego persistir el resultado o el siguiente estado.

Eso permite que el sistema sobreviva a reinicios sin perder contexto. También te deja consultar con SQL qué quedó pendiente, qué falló y qué lleva más tiempo del esperado.

Ejemplo de esquema mínimo

No necesitas una estructura enorme para empezar. Algo así suele bastar para un caso inicial:

CREATE TABLE workflows (
  id BIGSERIAL PRIMARY KEY,
  type TEXT NOT NULL,
  state TEXT NOT NULL DEFAULT 'pending',
  payload JSONB NOT NULL,
  attempts INT NOT NULL DEFAULT 0,
  locked_at TIMESTAMPTZ,
  last_error TEXT,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX workflows_state_created_at_idx
  ON workflows (state, created_at);

Con algo así ya puedes listar pendientes, reclamar trabajo sin duplicarlo y auditar errores. Si más adelante necesitas granularidad por paso, agregas una tabla de steps o events.

Un flujo típico de ejecución

  1. Insertas el workflow con su payload.
  2. Un worker toma un registro pending y lo marca running en una transacción.
  3. Ejecuta el paso externo, por ejemplo llamar a una API de pagos.
  4. Guarda el resultado o el error en la misma base.
  5. Si falla, incrementa attempts y decide si reintenta o pasa a failed.

Ese patrón funciona bien cuando el estado del negocio y el estado técnico viven cerca. No elimina los problemas de consistencia por arte de magia, pero sí hace más fácil razonar sobre ellos.

Qué ganas frente a una cola u orquestador dedicado

Una cola dedicada sigue siendo útil en muchos casos. Lo mismo pasa con un orquestador de workflows. El punto no es que Postgres los reemplace siempre, sino que en varios equipos el stack se sobredimensiona demasiado pronto. Si tu flujo no necesita millones de eventos por minuto ni una topología compleja de fan-out/fan-in, quizá te conviene empezar más simple.

La diferencia más visible está en la operación diaria. Una cola más un orquestador te obliga a revisar más componentes cuando algo falla. Con Postgres, muchas veces puedes depurar con una consulta y ver el estado real del proceso sin saltar entre sistemas.

Comparación rápida

OpciónVentaja principalCosto operativoCuándo encaja mejor
Postgres como workflow storeMenos piezas y transacciones clarasBajoEquipos pequeños o medianos, flujos acoplados a datos
Cola dedicadaBuen desacople y throughput altoMedioJobs simples, alto volumen, procesamiento asíncrono general
Orquestador de workflowsVisibilidad y control de pasos complejosAltoFlujos largos, múltiples ramas, dependencias entre servicios

Si trabajas en una startup en LatAm, esta decisión suele ser todavía más sensible. Menos infraestructura significa menos costo mensual, menos dependencia de especialistas y menos tiempo perdido en operación. En contextos donde el equipo de backend es de 2 a 6 personas, eso pesa bastante.

Cuándo sí se te queda corto

Postgres no es la respuesta ideal para todo. Se te puede quedar corto si:

  • tienes un volumen muy alto de eventos por segundo,
  • necesitas fan-out masivo entre muchos consumidores,
  • requieres workflows con muchas ramas y compensaciones complejas,
  • o quieres separar por completo la ejecución del almacenamiento.

En esos casos, una cola o un motor de workflows dedicado puede valer la pena. La clave es no asumir que necesitas esa complejidad desde el inicio.

Patrones que hacen que funcione bien

Si vas a usar Postgres para workflows durables, hay algunos patrones que te ahorran dolores de cabeza. El más importante es la idempotencia. Si un paso se ejecuta dos veces por un retry, el sistema no debería duplicar efectos externos. Eso significa usar claves únicas, estados bien definidos y verificaciones antes de ejecutar acciones irreversibles.

También conviene separar claramente los pasos que tocan sistemas externos de los pasos internos. Lo que cambia solo dentro de la base puede ir en una transacción. Lo que llama a una API externa casi siempre debe ejecutarse fuera de la transacción, pero con un registro previo y posterior que permita reanudar si algo falla.

Buenas prácticas concretas

  • Usa estados explícitos como pending, running, succeeded, failed.
  • Guarda un attempts count para controlar reintentos.
  • Registra locked_at o claimed_at para detectar trabajos atascados.
  • Usa UNIQUE constraints para evitar duplicados.
  • Separa el payload del estado para no mezclar datos de negocio con metadata operativa.
  • Define una política de retry con backoff, por ejemplo 3 intentos con esperas de 5, 30 y 120 segundos.

Si necesitas un modelo más robusto, puedes apoyarte en eventos. En vez de sobrescribir un único registro, guardas una secuencia de cambios: creado, reclamado, falló, reintentado, completado. Eso te da trazabilidad sin salir de Postgres.

Cuándo esta estrategia te simplifica de verdad

La ganancia aparece cuando el workflow está cerca del dominio principal de tu producto. Por ejemplo, onboarding de usuarios, cobros, provisioning de cuentas, sincronización con CRM, generación de reportes o procesamiento de archivos. Son casos donde el estado del proceso importa tanto como el resultado final.

También funciona bien cuando tu equipo quiere moverse rápido sin sumar demasiadas piezas. Si ya tienes Postgres, ya sabes operarlo y ya lo monitoreas, meterlo al centro del workflow reduce el salto mental. No necesitas aprender otra consola para ver si un job quedó a medias.

Señales de que te conviene probarlo

  1. Tu sistema ya depende de Postgres como base principal.
  2. Los workflows son de baja o media complejidad.
  3. El equipo es pequeño y no quiere operar más servicios.
  4. Los errores más frecuentes son duplicados, retries y estados perdidos.
  5. El negocio necesita trazabilidad simple, no una orquestación de alto nivel.

Si cumples varias de esas condiciones, vale la pena hacer un prototipo. No hace falta migrar todo. Puedes empezar con un flujo concreto y medir cuántas piezas eliminas y cuánto tiempo ahorras en debugging.

Tabla resumen

Pregunta cortaRespuesta corta
¿Postgres reemplaza siempre a una cola?No, pero puede cubrir muchos workflows internos sin sumar otra pieza.
¿Qué problema resuelve mejor?Persistir estado y coordinar reintentos de forma durable.
¿Qué necesitas para empezar?Una tabla de workflows, estados claros e idempotencia.
¿Cuándo no conviene?Cuando hay alto volumen, muchas ramas o desacople fuerte entre servicios.
¿Qué gana un equipo pequeño?Menos infraestructura, menos operación y debugging más simple.
¿Qué dato debes guardar sí o sí?Estado actual, intentos y timestamps de bloqueo o actualización.

En la práctica, usar Postgres para workflows durables no significa negar que existan herramientas especializadas. Significa elegir la herramienta más simple que cubra tu caso real. Si tu backend todavía puede vivir con una base bien diseñada, quizá no necesitas una cola, un scheduler y un orquestador para resolver algo que Postgres ya sabe hacer bastante bien.

Preguntas frecuentes

¿Postgres sirve para cualquier workflow durable?
No. Sirve muy bien para flujos acoplados a datos y de complejidad moderada, pero no reemplaza a un motor especializado cuando tienes muchas ramas, alto volumen o coordinación entre varios servicios. La decisión depende del tipo de proceso que quieres ejecutar y del costo operativo que estás dispuesto a asumir.
¿No es mala idea usar la base de datos como cola?
Depende de cómo lo hagas. Si usas Postgres con estados claros, locks correctos e idempotencia, puede funcionar muy bien para muchos casos reales. El problema aparece cuando lo conviertes en una cola improvisada sin control de concurrencia ni observabilidad.
¿Qué gana un equipo pequeño o mediano con este enfoque?
Gana simplicidad. Menos servicios significa menos configuración, menos monitoreo y menos puntos de falla. También facilita que todo el equipo entienda el flujo mirando SQL y no varias herramientas distintas.
¿Cómo evito procesar un workflow dos veces?
Usa idempotencia y una estrategia clara de claim del trabajo. Eso suele incluir una restricción única, un cambio de estado atómico y una verificación antes de ejecutar acciones externas. Si el proceso se repite, no debería duplicar efectos.
¿Necesito tablas separadas para pasos y eventos?
No siempre, pero ayuda cuando el flujo crece. Para casos simples, una tabla de workflows con metadata puede bastar. Si quieres trazabilidad fina, auditoría o reanudación por etapa, una tabla de eventos o steps te da más control.
¿Esto aplica bien para equipos en LatAm?
Sí, especialmente cuando el equipo quiere reducir costo operativo y evitar contratar más infraestructura de la necesaria. En contextos donde el presupuesto y el tiempo de operación importan mucho, simplificar el backend con Postgres puede ser una ventaja real.
¿Cuándo debería pasarme a una cola u orquestador dedicado?
Cuando el volumen, la complejidad o el desacople lo justifiquen. Si tienes muchos consumidores, workflows largos con compensaciones o requerimientos fuertes de escalado, una herramienta especializada puede darte mejor ergonomía y rendimiento.

Azirgo

¿Listo para construir tu Producto Digital?

Sitios web, apps móviles, software a medida y soluciones blockchain. Cuéntanos qué tienes en mente y armamos un plan claro contigo.

  • Cotización clara en 48 horas
  • Equipo en Ecuador, atención en español
  • Desde un MVP hasta un producto en producción