new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Temporal · Develop · all subjects

workflows/timers

55 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

PHP Workflow timer function

To set a timer in PHP, use Workflow::timer() and pass the number of seconds you want to wait before continuing. Example: yield Workflow::timer(300); sleeps for 5 minutes.

Timers can run for extended durations

A Workflow can sleep for months using timers.

Timer invocations cannot be inside await methods

You cannot set a Timer invocation inside the await or awaitWithTimeout methods.

Timers are resource-light and scalable

Timers do not tie up the process and are a resource-light operation. Millions of timers can run off a single Worker.

Add summary metadata to timers in workflows

When creating a Timer (using workflow.sleep()) from within a Workflow, you can attach a summary parameter. The summary is a string limited to 200 bytes that provides context about the Timer.

Python example: create timer with summary

```python @workflow.defn class YourWorkflow: @workflow.run async def run(self, input: str) -> str: # Create a timer with a summary await workflow.sleep(timedelta(minutes=5), summary="Waiting for payment confirmation") return "Timer completed" ``` This example demonstrates how to add a summary to a Timer.

Cron schedule workflow example in Python

import asyncio from temporalio.client import Client from your_workflow import CronWorkflow async def main(): client = await Client.connect("localhost:7233") result = await client.execute_workflow( CronWorkflow.run, id="your-workflow-id", task_queue="your-task-queue", cron_schedule="* * * * *", ) print(f"Results: {result}") if __name__ == "__main__": asyncio.run(main())

Set Cron schedule for workflow in Python

You can set each workflow to repeat on a schedule using the `cron_schedule` option in either the `start_workflow()` or `execute_workflow()` asynchronous methods on the Client.

Start delay workflow example in Python

import asyncio from datetime import timedelta from temporalio.client import Client from your_workflow import YourWorkflow async def main(): client = await Client.connect("localhost:7233") result = await client.execute_workflow( YourWorkflow.run, "your name", id="your-workflow-id", task_queue="your-task-queue", start_delay=timedelta(hours=1, minutes=20, seconds=30) ) print(f"Result: {result}") if __name__ == "__main__": asyncio.run(main())

Start delay workflow in Python

Use the `start_delay` option to schedule a workflow execution at a specific one-time future point rather than on a recurring schedule. Use the `start_delay` option in either the `start_workflow()` or `execute_workflow()` asynchronous methods on the Client.

Temporal Cron Jobs deprecation notice

Cron support is not recommended. Schedules should be used instead of Cron Jobs. Schedules were built to provide a better developer experience, including more configuration options and the ability to update or pause running Schedules.

Example: Setting workflow execution timeout in Python

import asyncio from datetime import timedelta from temporalio.client import Client from your_workflows import YourWorkflow async def main(): client = await Client.connect("localhost:7233") result = await client.execute_workflow( YourWorkflow.run, "your timeout argument", id="your-workflow-id", task_queue="your-task-queue", execution_timeout=timedelta(seconds=2), ) print(f"Result: {result}") if __name__ == "__main__": asyncio.run(main()) This example shows how to set the execution_timeout parameter when executing a workflow. The run_timeout and task_timeout parameters can be set in the same way.

How to set workflow timeouts in Python

Set Workflow timeouts using the execution_timeout, run_timeout, or task_timeout parameters when calling either the start_workflow() or execute_workflow() asynchronous methods on the Client.

Python timer with asyncio.sleep()

To set a Timer in Python workflows, call asyncio.sleep() and pass the duration in seconds. This creates a durable timer that will resolve even if the Worker or Temporal Service is down when the time period completes.

Python asyncio.sleep() in workflow example

Example of using asyncio.sleep() in a Python workflow: ```python import asyncio from temporalio import workflow @workflow.defn class LoopingWorkflow: @workflow.run async def run(self, iteration: int) -> None: if iteration == 5: return await asyncio.sleep(10) workflow.continue_as_new(iteration + 1) ``` This example shows a workflow that sleeps for 10 seconds before continuing as a new workflow execution.

Workflows can sleep for extended periods

A Workflow can set a durable Timer for a fixed time period and sleep for months using Temporal's durable timer mechanism.

Timers are persisted and resource-light

Timers are persisted in Temporal, so code execution resumes after Worker or Temporal Service downtime. Sleeping is a resource-light operation that does not tie up the process, allowing millions of Timers to run off a single Worker.

summary parameter for timers in Ruby workflows

When creating a timer using Temporalio::Workflow.sleep() in the Ruby SDK, you can provide a summary parameter. This is a string limited to 200 bytes that provides context for the timer and appears in the Temporal UI Timeline and Event History.

Example: Create timer with summary in Ruby

require 'temporalio' class YourWorkflow < Temporalio::Workflow::Definition def execute(input) # Create a timer with a summary Temporalio::Workflow.sleep(300, summary: 'Waiting for payment confirmation') 'Timer completed' end end

Workflow Task Timeout definition

Workflow Task Timeout limits the time allowed for a Worker to process a Workflow Task.

Workflow timeouts types

There are three types of Workflow timeouts: Workflow Execution Timeout limits how long the full Workflow Execution can run; Workflow Run Timeout limits the duration of an individual run of a Workflow Execution; Workflow Task Timeout limits the time allowed for a Worker to process a Workflow Task.

Set Workflow timeouts as keyword parameters

Workflow timeouts are set as keyword parameter options when starting a Workflow using execute_workflow or start_workflow methods in the Ruby SDK.

Ruby SDK Workflow timeout example

Example of setting execution_timeout in Ruby: result = my_client.execute_workflow(MyWorkflow, 'some-input', id: 'my-workflow-id', task_queue: 'my-task-queue', execution_timeout: 5 * 60). The execution_timeout value is specified in seconds.

Workflow Execution Timeout definition

Workflow Execution Timeout limits how long the full Workflow Execution can run.

Workflow Run Timeout definition

Workflow Run Timeout limits the duration of an individual run of a Workflow Execution.

Temporalio::Workflow.sleep syntax with summary parameter

Temporalio::Workflow.sleep accepts a duration in seconds as the first parameter and an optional summary parameter. The summary parameter allows you to set a label that will be displayed in the UI to describe the timer purpose. Example: Temporalio::Workflow.sleep(72 * 60 * 60, summary: 'my timer')

Timer resource efficiency in Ruby SDK

Sleeping is a resource-light operation that does not tie up the process. A single Worker can run millions of Timers efficiently.

Kernel#sleep compatibility in Ruby workflows

Kernel#sleep technically works in workflows, but using Temporalio::Workflow.sleep is preferred because it allows setting a summary that will be displayed in the UI.

Timeout block execution in Ruby SDK

Use Temporalio::Workflow.timeout() method to timeout a set of code. It works like standard Ruby Timeout.timeout but is designed for workflow context.

Durable Timer basic usage in Ruby SDK

Use Temporalio::Workflow.sleep() to pause workflow execution for a specified duration. The duration is specified in seconds. Timers are persisted and will resolve even if the Worker or Temporal Service is down; as soon as they recover, the timer will resolve and code execution continues.

Workflow timeouts in Rust

Workflow timeouts in Rust are configured via WorkflowStartOptions when starting a Workflow Execution. Available timeout fields are execution_timeout, run_timeout, and task_timeout. Workflow Execution Timeout controls the maximum total time a Workflow Execution can run. Workflow Run Timeout controls the maximum time a single Workflow Run can last. Workflow Task Timeout controls the maximum time a Worker can take to complete a Workflow Task.

Rust WorkflowStartOptions timeout example

This example shows how to set Workflow timeouts in Rust using WorkflowStartOptions: let wf_handle = client.start_workflow( GreetingsWorkflow::run, (), WorkflowStartOptions::new( "my-task-queue", "greetings-workflow-10", ) .execution_timeout(Duration::from_secs(3600)) .run_timeout(Duration::from_secs(600)) .task_timeout(Duration::from_secs(10)) .build() ).await?;

TimerOptions struct fields in Rust

The TimerOptions struct in Rust has two fields: duration (required, Duration type) specifies how long to wait, and summary (optional, String type) provides a human-readable label for the timer.

Workflow sleep duration limits

Workflows can sleep for days, months, or even years using durable timers.

Rust timer() function syntax

To set a timer in Rust, use the timer() function on the workflow context with a TimerOptions struct containing duration and optional summary. The call is awaited. Example: ctx.timer(TimerOptions { duration: Duration::from_secs(60), summary: Some("important timer".into()) }).await;

Durable timers persist across downtime

Timers in Temporal workflows are persisted, so if a Worker or Temporal Service is down when the timer period completes, the timer will resolve and code execution continues as soon as the Worker and Service are back up.

Timers are resource-light operations

Sleeping via timers does not tie up the process, and millions of timers can run off a single Worker.

Time skipping for long-running Workflows

Long-running Workflows that persist for months or years can be tested by skipping time, allowing tests to complete in seconds rather than the actual sleep duration. For example, a Workflow sleep for a day or an Activity failure with a long retry interval can be tested without waiting the full duration.

Example: Manual time skipping test

import { sleep, defineQuery, setHandler } from '@temporalio/workflow'; export const daysQuery = defineQuery('days'); export async function sleeperWorkflow() { let numDays = 0; setHandler(daysQuery, () => numDays); for (let i = 0; i < 100; i++) { await sleep('1 day'); numDays++; } } test('sleeperWorkflow counts days correctly', async () => { const worker = await Worker.create({ connection: testEnv.nativeConnection, taskQueue: 'test', workflowsPath: require.resolve('./workflows'), }); handle = await testEnv.client.workflow.start(sleeperWorkflow, { workflowId: uuid4(), taskQueue, }); worker.run(); let numDays = await handle.query(daysQuery); assert.equal(numDays, 0); await testEnv.sleep('25 hours'); numDays = await handle.query(daysQuery); assert.equal(numDays, 1); await testEnv.sleep('25 hours'); numDays = await handle.query(daysQuery); assert.equal(numDays, 2); });

Manual time skipping with testEnv.sleep()

Call testEnv.sleep() from test code to advance the test server's time manually. This is useful for testing intermediate states or indefinitely long-running Workflows. To use testEnv.sleep(), start the Workflow with .start() instead of .execute() and avoid calling .result() to prevent automatic time skipping.

Example: Automatic time skipping test

import { sleep } from '@temporalio/workflow'; export async function sleeperWorkflow() { await sleep('1 day'); } test('sleep completes almost immediately', async () => { const worker = await Worker.create({ connection: testEnv.nativeConnection, taskQueue: 'test', workflowsPath: require.resolve('./workflows'), }); await worker.runUntil( testEnv.client.workflow.execute(sleeperWorkflow, { workflowId: uuid(), taskQueue: 'test', }), ); });

Automatic time skipping in tests

The test server starts in normal time. When using TestWorkflowEnvironment.client.workflow.execute() or .result(), the test server switches to skipped time mode until the Workflow completes. In skipped mode, timers (sleep() calls and condition() timeouts) are fast-forwarded except when Activities are running.

Example: timer with summary using sleep

import { sleep } from '@temporalio/workflow'; export async function yourWorkflow(input: string): Promise<string> { await sleep('5 minutes', { summary: 'Waiting for payment confirmation' }); return 'Timer completed'; }

Timer summary using sleep options

You can attach a summary to timers within a workflow by passing a summary option to the sleep() function. The summary format is a string limited to 200 bytes.

Workflow Timeout configuration example

Workflow Timeouts are set when starting a Workflow. Example: await client.workflow.start(example, { taskQueue, workflowId, workflowExecutionTimeout: '1 day' }). Other timeout options include workflowRunTimeout: '1 minute' and workflowTaskTimeout: '30 seconds'.

Recommendation against setting Workflow Timeouts

Setting Workflow Timeouts is generally not recommended because Workflows are designed to be long-running and resilient. Setting a Timeout can limit the Workflow's ability to handle unexpected delays or long-running processes. If you need to perform an action inside your Workflow after a specific period of time, use a Timer instead.

Workflow timeout properties in WorkflowOptions

The following properties can be set on the WorkflowOptions interface when starting a Workflow: workflowExecutionTimeout, workflowRunTimeout, and workflowTaskTimeout. These are set when calling client.workflow.start() with the task queue and workflow ID.

Three types of Workflow Timeouts in TypeScript

Workflow Timeouts are set when starting a Workflow using either the Client or Workflow API. Workflow Execution Timeout restricts the maximum amount of time that a single Workflow Execution can be executed. Workflow Run Timeout restricts the maximum amount of time that a single Workflow Run can last. Workflow Task Timeout restricts the maximum amount of time that a Worker can execute a Workflow Task.

UpdatableTimer Implementation

UpdatableTimer implementation using wf.condition() to enable deadline updates via signals. ```ts export class UpdatableTimer implements PromiseLike<void> { deadlineUpdated = false; #deadline: number; constructor(deadline: number) { this.#deadline = deadline; } private async run(): Promise<void> { while (true) { this.deadlineUpdated = false; if ( !(await wf.condition( () => this.deadlineUpdated, this.#deadline - Date.now(), )) ) { break; } } } then<TResult1 = void, TResult2 = never>( onfulfilled?: (value: void) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>, ): PromiseLike<TResult1 | TResult2> { return this.run().then(onfulfilled, onrejected); } set deadline(value: number) { this.#deadline = value; this.deadlineUpdated = true; } get deadline(): number { return this.#deadline; } } ``` This implementation is available in the third-party package temporal-time-utils on npm.

Updatable Timer Pattern

An Updatable Timer can be built using the condition() function to create a timer that resolves earlier if a new deadline is sent via Signal. This pattern allows dynamic adjustment of timer deadlines during workflow execution.

Antipattern: Racing chained sleep promises

Be careful when racing a chained sleep().then(). This causes bugs because the chained .then() will still continue to execute after the race resolves, leading to unexpected state changes. The then handler executes regardless of whether that branch of the race won.

Racing Timers Example - Order Processing

Example showing how to race a timer against an order processing promise. If processing takes longer than the timeout, send a notification email. ```ts export async function processOrderWorkflow({ orderProcessingMS, sendDelayedEmailTimeoutMS, }: ProcessOrderOptions): Promise<void> { let processing = true; const processOrderPromise = processOrder(orderProcessingMS).then(() => { processing = false; }); await Promise.race([processOrderPromise, sleep(sendDelayedEmailTimeoutMS)]); if (processing) { await sendNotificationEmail(); await processOrderPromise; } } ```

Racing Timers with Promise.race

Use Promise.race() with sleep() to dynamically adjust delays. This pattern is useful for sending notifications only if processing exceeds a timeout threshold.

Timers in Workflows - Definition

A Workflow can set a durable Timer for a fixed time period. In TypeScript SDK, the function is called sleep(). Timers are persisted, so even if your Worker or Temporal Service is down when the time period completes, as soon as they are back up, the sleep() call will resolve and code continues executing. A Workflow can sleep for months. Sleeping is resource-light: it does not tie up the process, and you can run millions of Timers off a single Worker.

Updatable Timer Example

Example showing a countdown workflow with an updatable timer that receives new deadlines via signals and allows querying remaining time. ```ts import * as wf from '@temporalio/workflow'; export async function countdownWorkflow(): Promise<void> { const target = Date.now() + 24 * 60 * 60 * 1000; // 1 day!!! const timer = new UpdatableTimer(target); console.log('timer set for: ' + new Date(target).toString()); wf.setHandler(setDeadlineSignal, (deadline) => { timer.deadline = deadline; console.log('timer now set for: ' + new Date(deadline).toString()); }); wf.setHandler(timeLeftQuery, () => timer.deadline - Date.now()); await timer; console.log('countdown done!'); } ```

Give your agent this brain