Saltar al contenido
Volver a Insights
Arquitectura10 min de lectura

Ejecución durable vs. el patrón Saga para flujos de pago

Las compensaciones Saga son necesarias pero insuficientes. La ejecución durable proporciona garantías exactly-once que los procesos financieros requieren.

Ejecución Durable vs. Patrón Saga: Eligiendo el Modelo de Workflow Correcto para Pagos


El paso 3 de 5 falla. El consumer de la cola se cae. Al reiniciar, ¿reproduce desde el paso 1? ¿Salta al paso 4? La respuesta depende de estado que la cola no rastrea.

Este es el problema central de los procesos financieros multi-paso. La apertura de cuenta requiere cuatro pasos coordinados: crear entidad, provisionar cuentas de ledger, asignar IBAN, activar verificación KYC. La ejecución de pago requiere cinco: validar, screenear, debitar, enviar a clearing, rastrear settlement. Cada paso depende del anterior. Cada paso tiene efectos secundarios que no pueden repetirse casualmente.

Dos patrones arquitectónicos abordan este problema. Lo resuelven de forma diferente, con diferentes trade-offs, y la elección importa más que la mayoría de las decisiones de arquitectura en un sistema de pagos.

El Patrón Saga

Las Sagas coordinan servicios independientes a través de transacciones compensatorias. Existen dos variantes.

Coreografía: cada servicio publica eventos. El siguiente servicio se suscribe y actúa. Cuando algo falla, el servicio fallido publica un evento de compensación, y los servicios upstream escuchan y deshacen su trabajo.

El atractivo es el desacoplamiento. Sin coordinador central. Cada servicio es dueño de su lógica. Añadir un nuevo paso es añadir un nuevo subscriber.

El problema es la visibilidad. El "proceso" no existe en ningún lugar como artefacto único. Es una propiedad emergente de flujos de eventos entre servicios. Debuggear un pago fallido requiere correlacionar logs a través de cada consumer que participó. Si un evento se perdió (y los eventos se pierden, particiones de red, crashes de consumer antes del acknowledgment, overflow de dead-letter), el fallo es silencioso. Ningún componente sabe que el proceso está incompleto, porque ningún componente rastrea el proceso.

Orquestación: un coordinador central envía comandos a cada servicio en secuencia. El coordinador conoce el paso actual. Si un paso falla, el coordinador ejecuta compensación en orden inverso.

Esto es mejor. El proceso es visible en un lugar. Un operador puede inspeccionar el estado del coordinador y ver: paso 3 de 5 está pendiente. El coordinador es la fuente única de verdad para el proceso.

Pero: el coordinador mismo debe sobrevivir fallos. Si el coordinador se cae entre el paso 3 (debitar la cuenta) y el paso 4 (enviar a clearing), ¿qué pasa? La respuesta depende de cómo el coordinador persiste su propio estado. Si usa una máquina de estados en memoria, el estado se pierde. Si persiste a una base de datos, la recuperación depende de si la escritura de base de datos se committeó antes del crash. La propia fiabilidad del coordinador se convierte en un problema de diseño, uno que la orquestación Saga no resuelve inherentemente.

Ambas variantes Saga comparten una propiedad fundamental: cada paso es una transacción independiente. La saga las coordina. Pero la coordinación misma no es transaccional. La brecha entre "paso 3 committeó" y "el coordinador registró que paso 3 committeó" es donde se esconde la pérdida de datos.

Ejecución Durable

La ejecución durable toma un enfoque diferente. El motor de workflows journaliza cada paso ANTES de ejecutarlo. El journal es el estado del proceso. Si el motor se cae y reinicia, reproduce el journal y reanuda en el punto exacto de interrupción.

El modelo mental es diferente de las Sagas. En una Saga, define la ruta forward y la ruta de compensación como preocupaciones separadas. En ejecución durable, escribe el workflow como una función lineal, paso 1, paso 2, paso 3, y el motor garantiza que la función se complete. Si un paso falla permanentemente (no un error transitorio, sino un fallo de negocio genuino, "la cuenta no existe"), el motor ejecuta la compensación como parte del mismo workflow journalizado.

Tres propiedades distinguen la ejecución durable de la orquestación Saga:

El journal sobrevive reinicios de proceso. El motor escribe cada paso en un log durable antes de la ejecución. Al reiniciar, reproduce el log y reanuda. El journal no es una optimización ni una ocurrencia tardía, es el mecanismo de ejecución. El proceso no corre "encima del" journal. El proceso ES el journal, reproducido.

La idempotencia es garantizada por el motor. En una Saga, cada servicio debe implementar idempotencia independientemente. Si el coordinador reintenta el paso 3, el servicio debe detectar el duplicado y retornar el resultado previo. En ejecución durable, el motor rastrea qué pasos se han completado. Al reproducir, los pasos completados retornan sus resultados cacheados sin re-ejecutar. El servicio no necesita ser idempotente, el motor asegura que se llame como máximo una vez por instancia de workflow.

El journal es la trilha de auditoría. Cada workflow tiene un ID de correlación. Cada paso se registra con entradas, salidas, duración y resultado. Un auditor puede reconstruir el ciclo de vida completo de un pago desde un solo identificador. No es una funcionalidad de logging, es una propiedad estructural del modelo de ejecución. La trilha de auditoría existe porque el journal existe, y el journal existe porque el motor no puede funcionar sin él.

Un Ejemplo Concreto: Transferencia SEPA

Recorra un pago con ambos patrones.

La ruta feliz (ambos patrones la manejan idénticamente):

  1. Validar IBAN y monto ✓
  2. Screening AML (proveedor externo) ✓
  3. Debitar cuenta del emisor (ledger) ✓
  4. Enviar a clearing (SEPA SCT vía CSM) ✓
  5. Rastrear estado de settlement ✓

El fallo: paso 4 es rechazado por la red de clearing.

La cuenta del emisor ha sido debitada (paso 3). La red de clearing rechazó el envío (paso 4). El débito debe revertirse.

Enfoque Saga:

El adaptador de clearing publica un evento PaymentRejected. Un consumer de compensación lo recoge, llama al ledger para revertir el débito, y publica DebitReversed. El registro del pago original se actualiza a FAILED.

Pero: ¿qué pasa si el consumer de compensación se cae antes de revertir el débito? El evento PaymentRejected queda en la dead-letter queue. La cuenta del emisor permanece debitada. Ningún componente rastrea activamente este estado. El descubrimiento depende de un run de reconciliación (horas o días después) o una queja del cliente.

La mitigación existe: colas persistentes con entrega at-least-once, monitoreo de salud de consumers, alertas de dead-letter. Cada mitigación es un sistema adicional para construir y mantener. La ruta de compensación se vuelve tan compleja como la ruta forward.

Enfoque de ejecución durable:

El paso 4 falla. El motor registra el fallo en el journal. Ejecuta el handler de compensación (revertir el débito) como el siguiente paso journalizado. Si el motor se cae durante la reversión, reproduce el journal al reiniciar y re-ejecuta la reversión (que es idempotente porque el motor cacheó el estado del paso).

La secuencia completa, ruta forward, fallo, compensación, está en un journal con un ID de correlación. Un operador inspecciona el workflow y ve:

Workflow: SEPA-CT-2026-02-21-00847
  Step 1: Validate        → OK (12ms)
  Step 2: AML Screen      → OK (340ms, provider: screening-svc)
  Step 3: Debit            → OK (0.4ms, transfer_id: 9a3f...)
  Step 4: Submit Clearing  → REJECTED (reason: AC03, invalid creditor account)
  Step 5: Compensate Debit → OK (0.3ms, reversal_id: b7c1...)
  Status: COMPENSATED

Sin análisis forense de logs. Sin dead-letter queue que monitorear. Sin reconciliación requerida para descubrir el fallo. El proceso es auto-documentante.

Dónde Encaja Cada Patrón

AspectoSaga (Coreografía)Saga (Orquestación)Ejecución Durable
Visibilidad del procesoDistribuida entre logs de eventosCoordinador centralJournal único con replay completo
Modelo de recuperaciónEventos de compensación (pueden perderse)Coordinador reanuda (si estado persistido)Replay de journal (garantizado)
Trilha de auditoríaRequiere agregación de logs entre serviciosLog del coordinador (punto único)Integrada, el journal ES la trilha
IdempotenciaCada servicio debe implementarCada servicio debe implementarGarantizada por el motor
Fallo parcialSilencioso si evento de compensación se pierdeIncierto si coordinador se cae mid-stepJournal sobrevive, replay reanuda
ComplejidadBaja (por servicio), alta (sistema)Media (coordinador), media (servicios)Baja (código de workflow), baja (infraestructura)
Mejor paraCoordinación loosely coupled, low-stakesOrquestación multi-servicioProcesos financieros con requisito exactly-once

Las Sagas no están equivocadas. Funcionan bien para coordinación que puede tolerar consistencia eventual: reservas de inventario, workflows de notificación, pipelines de analytics. La variante de coreografía excele cuando los servicios son verdaderamente independientes y el "proceso" es una conveniencia, no un requisito.

Para procesos financieros, donde cada paso tiene efectos secundarios irreversibles, donde la compensación debe ser demostrable, donde un auditor preguntará "muéstreme cada paso de este pago", la ejecución durable proporciona garantías más fuertes con menos complejidad operativa.

La Industria Ha Convergido

La evidencia es práctica, no teórica. La industria de pagos ha tomado su decisión:

  • Stripe usa Temporal (ejecución durable) para orquestación de pagos.
  • Revolut usa Temporal para flujos de pago críticos.
  • Wise migró de orquestación Saga hacia Temporal.
  • N26 usa Kafka + Sagas, y discute públicamente la complejidad operativa de la gestión de compensación.

El patrón es claro. Para rutas críticas de pago, la industria está convergiendo en ejecución durable. El modelo basado en journal proporciona la trazabilidad que los reguladores requieren (DORA Art. 11-12) y la visibilidad operativa que los equipos de ingeniería necesitan.


Leer más: Workflows, Motor de Ejecución Durable | Payments, Orquestación de Pagos


Fuentes: