Temporal es un motor de ejecución durable: tu código de workflow se reproduce desde un historial de eventos que queda persistido, así que un trabajo largo que se muere en el minuto 38 retoma desde el minuto 38 en vez de rehacer 38 minutos de llamadas al modelo que ya pagaste. Aquí te explico qué es, por qué el trabajo de agentes en particular lo pide a gritos, un quickstart listo para pegar, y las concesiones honestas, incluida la regla de determinismo que, si la rompes, te deja fallas raras que nadie logra reproducir.

En resumen
- Temporal corre workflows durables: tu código se reproduce desde un historial de eventos que queda persistido, así que una corrida que se cae retoma de forma determinista en vez de arrancar de cero.
- Los efectos secundarios viven dentro de las «activities», el único lugar donde se permite I/O, llamadas al modelo y aleatoriedad, y Temporal las reintenta con el backoff y los timeouts que tú le configures.
- Sácalo a relucir cuando la orquestación es larga, inestable, con plata en juego, o le toca esperar días por una persona o un evento externo; no lo uses para una cadena rápida de tres pasos.
- La regla de oro es el determinismo: nada de «Date.now», nada de random, nada de I/O directo dentro del código del workflow, o el replay se desvía y te salen fallas imposibles de reproducir.
- Es un motor de ejecución durable, no un modelo ni un framework de agentes: orquesta y reintenta los pasos; el razonamiento sigue saliendo de tus prompts.
Los trabajos de agentes son largos, inestables y caros de repetir. Un pipeline de investigación que se cae en el minuto 38 de una corrida de 40 minutos no debería rehacer 38 minutos de llamadas al modelo que ya pagaste, pero con un «try/catch» pelado y un bucle que reintenta todo desde el principio, eso es justo lo que pasa. La apuesta de Temporal es que escribas tu orquestación como código normal y corriente, y el motor se encarga de volverla durable: persiste cada paso en un historial de eventos y, después de una caída, reproduce ese historial para dejar tu función exactamente donde estaba. Aquí vamos con qué es la herramienta, por qué el trabajo de agentes te empuja hacia ella, un quickstart listo para pegar, y las concesiones que no salen en el marketing, empezando por la regla de determinismo que tarde o temprano muerde a todo el mundo.
Nota
Temporal es un motor de ejecución durable, no un modelo ni un framework de agentes. Orquesta y reintenta los pasos de un trabajo largo y persiste sus resultados, pero el razonamiento sigue saliendo de tus prompts, y la memoria de largo plazo sigue viniendo de tu propia base de datos. Mídelo por si logra que tu orquestación sobreviva a las caídas y retome limpio, no por si reemplaza el resto de tu stack.
01 · Qué es en realidad
Temporal divide tu código en dos tipos de cosas, y todo el modelo se sostiene sobre esa división.
Workflows son tu lógica de orquestación, el "qué pasa, en qué orden, con qué reintentos y esperas". El código de un workflow se ve como una función async normal: haces await de los pasos, ramificas, iteras y duermes. La trampa está en que ese código se reproduce. Temporal graba cada decisión y resultado en un historial de eventos, y cuando un worker retoma el workflow, después de una caída, un deploy, o simplemente porque lo agendaron en otra máquina, vuelve a correr tu función desde arriba, alimentándola con los resultados grabados para que avance de un tirón hasta donde se quedó. Desde afuera parece que la función "retomó"; por debajo se reprodujo de forma determinista.
Activities son donde vive el mundo real: llamadas HTTP, escrituras a base de datos, llamadas al modelo, leer el reloj, cualquier cosa no determinista o con efectos secundarios. Temporal corre cada activity una sola vez, graba su resultado, y en el siguiente replay te entrega ese resultado grabado en vez de volver a correrla. Las activities son además la unidad de reintento, le adjuntas una política de reintentos y timeouts a cada una, y Temporal vuelve a correr una activity fallida con backoff sin que tu código de workflow se entere de que pasó algo.
Lo que ganas con esa división:
- Retomar donde te quedaste. Una corrida que se muere a media marcha vuelve al paso exacto en el que estaba, con el resultado de cada activity ya completada intacto. Sin rehacer trabajo que ya estaba listo.
- Reintentos como ciudadano de primera clase. Los pasos inestables llevan una política de reintentos declarativa en vez de bucles armados a mano y regados por todo el código.
- Esperas largas que salen prácticamente gratis. Un workflow puede «dormir» durante días o esperar una señal externa sin mantener un proceso abierto. Es solo una entrada en el historial hasta que el timer dispara o llega la señal.
02 · Por qué el trabajo de agentes en particular
La mayoría del software no corre cuarenta minutos por request. El trabajo de agentes sí, y eso cambia las cuentas.
- Cada paso se paga. Cuando un paso es una llamada al modelo, rehacer trabajo ya terminado no solo es lento, es una segunda factura por un output que ya tenías. La reanudación durable convierte el "se cayó la corrida, empieza de nuevo" en "se cayó la corrida, sigue donde ibas", y en un pipeline largo esa diferencia es plata de verdad.
- Los pasos fallan de maneras curiosas. Rate limits, timeouts, 5xx pasajeros, una tool que se cae por un momento, eso es lo normal en un agente, no la excepción. Una política de reintentos por activity con backoff los maneja ahí mismo donde ocurren, así que un solo tropezón no te tumba media hora de trabajo.
- Las compuertas humanas son parte del flujo. "Redacta esto y luego espera a que una persona apruebe antes de enviar" es un patrón de lo más común. Temporal deja que un workflow se quede pausado esperando una señal el tiempo que haga falta, minutos o días, sin una espera frágil en memoria que un reinicio se llevaría por delante.
- El fan-out y los schedules vienen de fábrica. Dispara veinte activities de investigación en paralelo, recógelas y luego decide; o corre todo el pipeline en un cron. Eso ya viene incluido, no es algo que tengas que atornillarle por fuera.
// Dentro de un workflow: reintento + timeout declarativos sobre una llamada frágil al modelo.
import { proxyActivities } from '@temporalio/workflow'
import type * as acts from './activities'
const { callModel } = proxyActivities<typeof acts>({
startToCloseTimeout: '2m',
retry: { maximumAttempts: 3, backoffCoefficient: 2 },
})
export async function researchWorkflow(topic: string): Promise<string> {
const draft = await callModel({ topic, step: 'draft' })
const critique = await callModel({ draft, step: 'critique' })
return await callModel({ draft, critique, step: 'finalize' })
}
Si «callModel» falla en el paso de la crítica, Temporal reintenta solo esa activity con backoff. Si el proceso del worker se muere por completo después del draft, un replay vuelve a correr «researchWorkflow» pero reproduce el resultado grabado del draft en vez de pagarlo de nuevo, así que retomas en el paso de la crítica, no desde el principio.
03 · Cuándo echar mano de él (y cuándo no)
Usa Temporal cuando la orquestación es la parte difícil y cara del sistema:
- Pipelines de varios pasos, de varias horas, con plata en juego donde volver a correr desde cero ante un fallo no es opción.
- Flujos que esperan al mundo exterior, una aprobación humana, un webhook, un job de terceros que termina cuando termina.
- Fan-out agendado, jobs periódicos que reparten el trabajo entre muchas activities y necesitan que cada una se reintente por su cuenta.
- Cualquier cosa donde importe el "¿este paso ya corrió?" y no quieras armarte tú mismo la capa de idempotencia y de llevar la cuenta.
No lo uses cuando la tarea es una cadena rápida de tres pasos que termina en segundos y es barata de reintentar completa. Montar un cluster de Temporal (o darte de alta en Temporal Cloud), correr workers y aprender el modelo de determinismo es demasiada maquinaria para un flujo que podrías resolver con tres llamadas a función con await. Eso es infraestructura, no arquitectura.
Consejo
Una buena prueba de fuego: ¿una caída a mitad de este trabajo te costaría plata de verdad u obligaría a alguien a rehacer lo que ya hizo? Si la respuesta es sí, la ejecución durable seguramente está justificando su lugar. Si una caída solo significa "córrelo otra vez, es barato y rápido", no necesitas Temporal, una función pelada y un decorador de reintentos es la respuesta honesta.
Cómo se compara
- vs. un bucle de reintento pelado: un bucle reintenta una sola llamada; Temporal vuelve durable y retomable toda la orquestación de varios pasos. Das el salto cuando lo que tiene que sobrevivir a una caída es el pipeline completo, no un solo request.
- vs. un runtime de grafos (LangGraph): esos orquestan los pasos de razonamiento de un agente sobre estado con forma de modelo, dentro del mismo proceso. Temporal orquesta jobs durables entre servicios y a lo largo del tiempo, sobreviviendo a reinicios y deploys. Otro nivel de abstracción; de hecho es común correr la lógica de un grafo dentro de una activity de Temporal.
- vs. n8n: n8n es buenísimo para conectar sistemas entre sí con un editor visual y es por donde yo arranco cuando se trata del pegamento entre integraciones. Das el salto a Temporal cuando necesitas control a nivel de código, garantías estrictas de durabilidad, y corridas que se miden en horas o días.
04 · Quickstart
Instala los paquetes del SDK de TypeScript:
npm install @temporalio/client @temporalio/worker @temporalio/workflow @temporalio/activity
Necesitas tres piezas: una activity (donde viven los efectos secundarios), un worker que hospeda tu workflow y tus activities y se conecta a un servicio de Temporal, y un client que arranca corridas. El workflowId es tu clave de idempotencia y tu manija para retomar o enviar señales más adelante:
// activities.ts — solo efectos secundarios; aquí sí se permite I/O.
export async function callModel(input: unknown): Promise<string> {
// aquí va la llamada real al modelo; Temporal graba el resultado.
return 'resultado para ' + JSON.stringify(input)
}
// worker.ts — hospeda el workflow + activities y hace polling de una task queue.
import { Worker } from '@temporalio/worker'
import * as activities from './activities'
const worker = await Worker.create({
workflowsPath: require.resolve('./workflows'),
activities,
taskQueue: 'research',
})
await worker.run()
// start.ts — dispara una corrida durable desde donde sea.
import { Connection, Client } from '@temporalio/client'
import { researchWorkflow } from './workflows'
const client = new Client({ connection: await Connection.connect() })
const handle = await client.workflow.start(researchWorkflow, {
args: ['pipelines de agente durables'],
taskQueue: 'research',
workflowId: 'research-2026-01-22', // dedupea + te deja reanudar
})
console.log(await handle.result())
Para desarrollo local, corre un servicio de dev (la CLI de Temporal trae uno) para que el worker tenga a qué conectarse. El mismo código apunta a un cluster self-hosted o a Temporal Cloud en producción con solo cambiar la conexión.
05 · La regla de determinismo
Esta es la que muerde a todo el mundo exactamente una vez, así que se gana su propia sección. Como el código de workflow se reproduce desde el historial, tiene que producir las mismas decisiones cada vez que corre sobre ese mismo historial. Cualquier cosa que pudiera devolver un valor distinto en el replay rompe esa garantía.
Dentro del código de workflow, no:
- Llames a Date.now ni leas el reloj del sistema directamente, usa las APIs de tiempo del SDK, que son seguras para workflows.
- Uses Math.random ni generes UUIDs en línea, pásalos por parámetro u obtenlos desde una activity.
- Hagas I/O directo, nada de «fetch», nada de llamadas a base de datos, nada de leer archivos. Todo eso va en activities.
- Dependas del orden de iteración de estructuras no deterministas ni de estado del entorno que pueda cambiar entre un replay y otro.
Rompe la regla y el replay se desvía: el motor reproduce el historial esperando la decisión A, tu código ahora no determinista produce la decisión B, y te sale un error de ejecución no determinista, o peor, un resultado sutilmente equivocado. Las fallas son desconcertantes justo porque solo aparecen en el replay, no en la primera corrida, así que pasan cualquier prueba rápida y revientan en producción después de una caída.
Atención
Aprende las restricciones de determinismo antes de escribir tu primer workflow, no después. La trampa está en que el código de workflow no determinista funciona perfecto en el camino feliz. La divergencia solo aparece cuando una caída obliga a un replay. Mete las llamadas al modelo, las lecturas del reloj y la aleatoriedad en activities desde el día uno, y trata la función del workflow como orquestación pura: ella decide, las activities actúan.
Una segunda disciplina muy de la mano: el versionado. Una vez que un workflow lleva un tiempo corriendo en producción, cambiarle el código puede romper el replay de las corridas en vuelo cuyo historial se grabó contra la lógica vieja. Temporal te da APIs de versionado (patching) para hacer evolucionar el código de workflow sin riesgo; apréndelas antes de enviar un cambio a un workflow que tiene corridas de larga vida en curso.
06 · Concesiones honestas
Temporal es la herramienta correcta para toda una clase de problemas reales, y no sale gratis:
- Es peso operativo. Corres un servicio de Temporal (cluster o Cloud) más los procesos worker. Para un fundador solo con un único VPS, eso es otra pieza móvil que hay que mantener sana, vale la pena para trabajos largos y genuinamente durables, exagerado para los cortos.
- El modelo mental tiene su curva. Workflows vs. activities, replay, determinismo y versionado son conceptos que tienes que tener presentes todo el tiempo. Hasta que te hacen clic, vas a escribir código de workflow que funciona en el camino feliz y falla misteriosamente en el replay.
- El estado durable es estado que ahora te toca administrar a ti. Los historiales se acumulan; necesitas políticas de retención y limpieza, y tienes que tratar lo que guardas como tratarías cualquier base de datos, incluida la parte de que los resultados intermedios de las activities pueden cargar datos sensibles.
- El desarrollo local necesita un servicio corriendo. No puedes simplemente hacer «node script.js», hay un dev server y un worker metidos en el loop, lo que le suma fricción al ciclo interno comparado con una función pelada.
La recompensa es concreta y grande cuando encaja: un pipeline de agente largo que sobrevive a caídas, deploys y compuertas humanas de un día entero sin que tú tengas que armar a mano la idempotencia, los reintentos y la lógica de retomar, justo el tipo de contabilidad que es tediosa de escribir y fácil de equivocar en los detalles.
Temporal se gana su peso cuando una caída a mitad de un trabajo costaría plata de verdad u obligaría a alguien a rehacer lo hecho, y cuando tus flujos esperan a personas o al mundo exterior durante horas. Échale mano en el momento en que "empezar de nuevo ante un fallo" deja de ser aceptable, mete cada efecto secundario en una activity, y respeta el determinismo desde tu primer workflow. Sáltatelo para cadenas cortas, baratas y de reintenta-todo, ahí una función pelada es la respuesta honesta, y un cluster de ejecución durable sería pura maquinaria que tendrías que andar cuidando.
Puntos clave
- Temporal vuelve durable la orquestación: el código se reproduce desde un historial persistido, así que una corrida que se cae retoma en el paso exacto en que se murió, con el trabajo ya terminado intacto.
- Divide todo en workflows deterministas (la orquestación) y activities (todo el I/O, las llamadas al modelo, los relojes, la aleatoriedad), el modelo completo depende de esa división.
- Échale mano en pipelines largos, inestables y con plata en juego, y en flujos que esperan días por personas o eventos externos; no lo uses en cadenas cortas, baratas y de reintenta-todo.
- Respeta el determinismo desde tu primer workflow: nada de «Date.now», nada de random, nada de I/O directo en el código del workflow, o el replay se desvía hacia fallas imposibles de reproducir.
- Es peso operativo que ahora te toca administrar a ti, un servicio que correr, historiales que retener, y versionado que aprender antes de tocar un workflow con corridas de larga vida en vuelo.
Preguntas frecuentes
¿Cuál es la diferencia entre un workflow y una activity?
Un workflow es tu lógica de orquestación, el orden de los pasos, los reintentos, las esperas, y se reproduce desde el historial, así que tiene que ser determinista. Una activity es donde se permiten los efectos secundarios y el no determinismo: llamadas HTTP, escrituras a base de datos, llamadas al modelo, leer el reloj, aleatoriedad. Temporal corre cada activity una sola vez, graba su resultado, y en el replay te entrega ese resultado grabado en vez de volver a correrla. La regla práctica: si un paso toca el mundo exterior o podría devolver un valor distinto dos veces, va en una activity; el workflow solo decide.
¿Por qué mi workflow falla solo después de una caída y nunca en la primera corrida?
Casi con seguridad es una violación de determinismo. El código de workflow se reproduce desde el historial, así que cualquier cosa no determinista, «Date.now», «Math.random», un UUID en línea, un «fetch» directo, produce en el replay un valor distinto del que el motor grabó la primera vez, y el replay se desvía. En la primera corrida no hay replay, así que el bug es invisible; solo asoma cuando una caída obliga a Temporal a volver a correr tu función sobre el historial grabado. El arreglo es mover cada lectura del reloj, valor aleatorio y llamada de I/O a una activity, y dejar la función del workflow como orquestación pura.
¿Cuándo es Temporal demasiado para lo que necesitas?
Cuando el trabajo es corto, barato de reintentar completo y no espera nada externo, una cadena rápida de tres pasos que termina en segundos y no cuesta nada volver a correr. Ahí la garantía de durabilidad no te aporta nada, y a cambio pagas un servicio que operar, workers que correr y un modelo de determinismo que aprender. La respuesta honesta en ese caso es una función async pelada con un decorador de reintentos. Da el salto a Temporal cuando una caída a media corrida costaría plata de verdad u obligaría a una persona a rehacer lo hecho, o cuando los flujos esperan a personas o al mundo exterior durante horas.
¿Cómo hace un workflow para esperar días por una aprobación humana sin mantener un proceso abierto?
Espera por una señal, y esa espera no es más que una entrada en el historial persistido, no un proceso bloqueado en memoria. El workflow llega al punto donde hace await de la señal de aprobación, Temporal graba que está esperando, y el worker queda libre para hacer otro trabajo o hasta apagarse. Cuando una persona finalmente envía la señal (a través del client, identificada por el workflowId), Temporal despierta el workflow y este continúa exactamente desde ese punto. Como la espera vive en el historial durable, sobrevive a reinicios, deploys y caídas, y eso es justo lo que vuelve prácticas las compuertas humanas de un día entero en lugar de un timer frágil en memoria.
¿Puedo cambiar el código de un workflow mientras todavía hay corridas viejas en curso?
Sí, pero con cuidado y con las APIs de versionado. Como las corridas en vuelo se reproducen contra el historial grabado bajo la lógica vieja, un cambio de código hecho a la ligera puede hacer que su replay se desvíe y falle. El patching/versionado de Temporal te deja ramificar el comportamiento para que las corridas viejas reproduzcan el camino viejo mientras las nuevas toman el nuevo. Para workflows de vida corta que terminan rápido, muchas veces basta con hacer el deploy y dejar que las viejas se vayan vaciando. Para corridas de larga vida, los jobs de un día o una semana que son toda la razón por la que usas Temporal, aprende patching antes de enviar un cambio, o vas a romper justamente las corridas que eran el sentido de tener durabilidad.
¿Tengo que alojar Temporal yo mismo o hay una opción gestionada?
Existen las dos. Puedes alojar tú mismo el servicio open-source de Temporal (respaldado por una base de datos como PostgreSQL) en tu propia infraestructura, o usar Temporal Cloud, el servicio gestionado, y ahorrarte operar el cluster. Tu código de workflow, activity y worker es idéntico en cualquiera de los dos casos, lo único que cambia es la conexión. Para un fundador solo con un único VPS, la cuenta es si prefieres cargar con el peso operativo del cluster o pagar el tier gestionado; para trabajos largos y genuinamente durables, cualquiera de los dos le gana a armar a mano la lógica de retomar, pero no te metas a alojar tú mismo un servicio con estado a la ligera si un bucle corto de reintentos te resolvería.
¿Prefieres que lo hagamos por ti?
Esto mismo lo construimos para negocios como el tuyo. La primera conversación es gratis y sin compromiso.
Escríbenos por WhatsAppPrimera conversación gratis. Te responde el fundador.
Recursos relacionados

Director, no solista: cómo orquestar Claude Code con subagentes
Una nota de campo sobre usar los subagentes de Claude Code como obreros y dejar el hilo principal como director: cuándo abrir en abanico, cuándo encadenar, cómo las salidas estructuradas frenan la deriva y los modos de falla de los que nadie te avisa.

LangGraph: grafos de agentes con estado que sí puedes depurar
LangGraph modela un agente como un grafo dirigido con estado compartido y tipado: los nodos son pasos, las aristas son decisiones, y los bucles y reintentos quedan a la vista en vez de escondidos dentro del prompt. Aquí va qué es, cuándo vale la pena la ceremonia frente al SDK directo, cómo montar uno en unos minutos y las concesiones sin maquillaje, incluida la trampa de los reducers que se come tu historial de mensajes sin avisar.

Agentes de IA: cómo delegar trabajo sin soltar el control
Un chatbot responde una pregunta. Un agente recibe un objetivo, usa herramientas, avanza por pasos y vuelve con un resultado. Esta guía explica el salto de pedir texto a delegar trabajo útil, con un encargo simple que puedes copiar hoy.