Tasks

Wait Tasks

Complete guide to wait tasks for synchronization, delays, and signal-based coordination in Compozy workflows

Overview

Wait tasks enable event-driven coordination in workflows by pausing execution until specific conditions are met, signals are received, or timeouts occur. They are essential for building reactive architectures, coordinating workflow patterns, and integrating with external systems through the Event API.

Signal-Based Waiting

Pause until specific signals arrive from workflows or external systems

Conditional Processing

Filter signals with CEL expressions and custom processors

Timeout Management

Handle timeouts with fallback strategies and retry policies

Dynamic Configuration

Use templates for signal names and processing parameters

External Integration

Coordinate with external APIs, databases, and services

Human Coordination

Support approval workflows and manual intervention points

Quick Start

New to wait tasks? Start with these essential concepts:

Task Configuration

Wait tasks require specific configuration fields to define their behavior. Below are the essential and optional configuration properties:

Configuration Properties

PropertyTypeRequiredDescription
typestringMust be "wait" to identify this as a wait task
wait_forstringSignal identifier to listen for - supports template expressions
timeoutstringMaximum wait duration (e.g., 5m, 300s, 1h) - prevents indefinite blocking
processorobjectBasic, composite, or agent task to process received signals
on_timeoutstringTask ID to execute when timeout occurs - enables workflow patterns
conditionstringtemplate expressions for signal filtering and validation
retry_policyobjectAutomatic retry configuration for resilient wait operations

Signal Configuration Patterns

Use fixed signal identifiers for predictable coordination:

# Wait for a specific signal
- id: wait-deployment-complete
  type: wait
  wait_for: "deployment-finished"
  timeout: 10m

# Wait for user interaction
- id: wait-user-confirmation
  type: wait
  wait_for: "user-confirmed"
  timeout: 1h

  outputs:
    confirmation_time: "{{ .signal.metadata.received_at_utc }}"
    user_decision: "{{ .signal.payload.decision }}"

Signal Processors

Processors enable custom handling of received signal data using tools, agents, or composite tasks before the workflow continues:

Use TypeScript tools for structured data processing:

- id: wait-and-process
  type: wait
  wait_for: "data-available"
  timeout: 2m

  processor:
    type: basic
    $use: tool(local::tools.#(id=="data-processor"))
    with:
      signal_data: "{{ .signal.payload }}"
      received_at: "{{ .signal.metadata.received_at_utc }}"
      signal_id: "{{ .signal.metadata.signal_id }}"

  outputs:
    processed_data: "{{ .processor.output.result }}"
    processing_time: "{{ .processor.output.duration }}"
  • Fast Execution

    Tools run in the Bun runtime for optimal performance

  • Type Safety

    TypeScript provides compile-time validation and better debugging

  • Deterministic

    Perfect for data transformation, validation, and API calls

Timeout & Resilience Patterns

Set appropriate timeouts based on expected response times:

- id: wait-with-timeout
  type: wait
  wait_for: "external-response"
  timeout: 30s

  # Execute specific task on timeout
  on_timeout: handle-timeout-case

  outputs:
    signal_received: "{{ not .task.timed_out }}"
    wait_duration: "{{ .task.duration }}"
    timeout_occurred: "{{ .task.timed_out }}"
  • Human Interactions

    Use longer timeouts (hours/days) for approval workflows and manual processes

  • API Responses

    Set shorter timeouts (seconds/minutes) for external service integration

  • Batch Processing

    Medium timeouts (minutes/hours) for data processing and report generation

Best Practices

Summary

Wait tasks are fundamental to building robust, coordinated workflows in Compozy. They enable sophisticated synchronization patterns, event-driven architectures, and reliable coordination between different parts of your system.

Next Steps