Simulating Workflows

Workflow simulation is a local execution environment that compiles your workflow to WebAssembly (WASM) and runs it on your machine. It allows you to test and debug your workflow logic before deploying it. The simulator makes real calls to public testnets and live HTTP endpoints, giving you high confidence that your code will work as expected when deployed.

When to use simulation

Use workflow simulation to:

  • Test workflow logic during development: Validate that your code behaves correctly before deploying.
  • Debug errors in a controlled environment: Catch and fix issues locally without deploying to a live network.
  • Test different trigger types: Manually select and test how your workflow responds to cron, HTTP, EVM log, or Solana log triggers.
  • Verify onchain interactions: Test read and write operations against real testnets.

Basic usage

The cre workflow simulate command compiles your workflow and executes it locally.

Basic syntax:

cre workflow simulate <workflow-name-or-path> [flags]

Example:

cre workflow simulate my-workflow --target staging-settings

What happens during simulation

  1. Compilation: The CLI compiles your workflow to WebAssembly (WASM). If you pass a pre-built binary with --wasm, the CLI skips this step. See Simulating with a pre-built binary.
  2. Trigger selection: You're prompted to select which trigger to test (cron, HTTP, EVM log, or Solana log).
  3. Execution: The workflow runs locally, making real calls to configured RPCs and HTTP endpoints.
  4. Output: The simulator displays logs from your workflow and the final execution result.

Prerequisites

Before running a simulation:

  • CRE account & authentication: You must have a CRE account and be logged in with the CLI. See Create your account and Log in with the CLI for instructions.
  • CRE CLI installed: You must have the CRE CLI installed on your machine. See CLI Installation for instructions.
  • Project configuration: You must run the command from your project root directory.
  • Valid workflow.yaml: Your workflow directory must contain a workflow.yaml file with correct paths to your workflow code, config, and secrets (optional).
  • RPC URLs configured: If your workflow interacts with blockchains, configure RPC endpoints in your project.yaml for the target you're using. Without this, the simulator cannot register the EVM capability and your workflow will fail. See Project Configuration for setup instructions.
  • Private key: Set CRE_ETH_PRIVATE_KEY in your .env file if your workflow performs onchain writes.

Interactive vs non-interactive modes

Interactive mode (default)

In interactive mode, the simulator prompts you to select a trigger and provide necessary inputs.

Example:

cre workflow simulate my-workflow --target staging-settings

What you'll see:

Workflow compiled

🚀 Workflow simulation ready. Please select a trigger:
1. cron-trigger@1.0.0 Trigger
2. http-trigger@1.0.0-alpha Trigger
3. evm:ChainSelector:16015286601757825753@1.0.0 LogTrigger

Enter your choice (1-3):

Select a trigger by entering its number, and follow any additional prompts for trigger-specific inputs.

Non-interactive mode

Non-interactive mode allows you to run simulations without prompts, making it ideal for CI/CD pipelines or automated testing.

Requirements:

  • Use the --non-interactive flag
  • Specify --trigger-index to select which handler to run (0-based position: 0 = first handler, 1 = second, etc.)
  • Provide trigger-specific flags as needed (see Trigger-specific configuration)

Example:

cre workflow simulate my-workflow --non-interactive --trigger-index 0 --target staging-settings

Listen mode

The --listen flag keeps the simulator alive and re-runs it for each incoming trigger event, instead of compiling and executing once then exiting.

  • HTTP triggers: starts a local HTTP server on port 2000 (change it with --http-trigger-port). Each POST request to /trigger triggers a simulation run.
  • EVM log triggers: watches the configured chain and re-runs on each matching log event.
cre workflow simulate my-workflow --listen --target staging-settings

This is useful when you want to send many test events without restarting the CLI. The simulator compiles your workflow once, when it starts, so restart it after you change your workflow code.

How listen mode handles HTTP requests

Keep the following behavior in mind when you send requests to the local HTTP server:

  • Request format: Send a POST request to http://localhost:2000/trigger with a JSON body of the form {"input": { ... }}. The simulator passes the value of input to your workflow as the trigger payload. Other body shapes, such as a gateway workflows.execute request, are not unwrapped. If input is missing, your workflow runs with an empty payload.
  • Response: The server returns an empty 200 OK as soon as it accepts the request, before the workflow runs. Logs and the workflow result appear in the terminal where the simulator is running, not in the HTTP response. A body that isn't valid JSON returns 400 Bad Request and does not start a run.
  • One run at a time: The simulator runs requests in order. It holds up to 16 pending requests and returns 429 Too Many Requests after that.
  • Rate limit: By default, the simulator enforces the production HTTP trigger service quota: one run per 30 seconds. The simulator skips requests that arrive sooner, prints Trigger rate limited, skipping execution in the terminal, and still returns 200 OK to the caller. To send requests more often, run with --limits none. See Testing Production Limits.
  • Errors: If your workflow returns an error, the simulator logs it and keeps listening. Errors raised by the simulation engine itself, such as exceeding a resource limit, end the session.
  • One workflow per simulator: Each --listen process serves a single workflow and trigger. To serve several workflows locally, start one simulator per workflow, each with its own --http-trigger-port.

See Testing HTTP Triggers in Simulation for a detailed walkthrough with HTTP triggers, including how the local server differs from the deployed gateway.

Simulating with a pre-built binary

By default, each cre workflow simulate run compiles your workflow to WASM. If you build the binary once and simulate it many times, for example in a CI/CD pipeline or from a script that starts several simulations, you can skip compilation.

There are two ways to do this:

  • --wasm flag: Build the binary with cre workflow build, then pass it to simulate. Your workflow.yaml stays unchanged.
  • Custom build: Convert the workflow with cre workflow custom-build. The CLI then runs the binary at wasm/workflow.wasm that your Makefile produces. This changes your workflow.yaml permanently.

Example using --wasm:

# Build once. The binary is written to ./my-workflow/binary.wasm by default
cre workflow build ./my-workflow --target staging-settings

# Simulate the pre-built binary as many times as you like
cre workflow simulate ./my-workflow --wasm ./binary.wasm --target staging-settings

When you pass --wasm:

  • The simulator runs the binary as-is and does not read your workflow source. If you change your code, rebuild the binary.
  • The simulator still reads your workflow.yaml for the config and secrets paths, and the target settings.
  • You can start several simulations at the same time against the same binary. They don't write build output, so they don't overwrite each other.
  • A relative path is resolved from the workflow directory, not from where you ran the command. In the example above, ./binary.wasm points to ./my-workflow/binary.wasm.
  • A local path can be at most 97 characters. If your path is longer, use a shorter location or a relative path.
  • The value can also be a URL, which the CLI downloads before it simulates.

The --broadcast flag

By default, the simulator performs a dry run for onchain write operations. It prepares the transaction but does not broadcast it to the blockchain.

To actually broadcast transactions during simulation, use the --broadcast flag:

cre workflow simulate my-workflow --broadcast --target staging-settings

Use case: Use --broadcast when you want to test the complete end-to-end flow, including actual onchain state changes, on a testnet.

Trigger-specific configuration

Different trigger types require different inputs for simulation.

Cron trigger

Cron triggers do not require additional configuration. When selected, they execute immediately.

Interactive example:

cre workflow simulate my-workflow --target staging-settings

Select the cron trigger when prompted (if multiple triggers are defined)

Non-interactive example:

# Assuming the cron trigger is the first trigger defined in your workflow (index 0)
cre workflow simulate my-workflow --non-interactive --trigger-index 0 --target staging-settings

HTTP trigger

HTTP triggers require a JSON payload.

Interactive mode:

When you select an HTTP trigger, the simulator prompts you to provide JSON input. You can:

  • Enter the JSON directly
  • Provide a file path (e.g., ./payload.json)

Non-interactive mode:

Use the --http-payload flag with:

  • A JSON string: --http-payload '{"key":"value"}'
  • A file path: --http-payload @./payload.json (with or without @ prefix)

Example:

cre workflow simulate my-workflow --non-interactive --trigger-index 1 --http-payload @./http_trigger_payload.json --target staging-settings

EVM log trigger

EVM log triggers require a transaction hash and event index to fetch a specific log event from the blockchain.

Interactive mode:

When you select an EVM log trigger, the simulator prompts you for:

  1. Transaction hash (e.g., 0x420721d7d00130a03c5b525b2dbfd42550906ddb3075e8377f9bb5d1a5992f8e)
  2. Event index (0-based index of the log in the transaction, e.g., 0)

The simulator fetches the log from the configured RPC and passes it to your workflow.

Non-interactive mode:

Use the --evm-tx-hash and --evm-event-index flags:

cre workflow simulate my-workflow \
  --non-interactive \
  --trigger-index 2 \
  --evm-tx-hash 0x420721d7d00130a03c5b525b2dbfd42550906ddb3075e8377f9bb5d1a5992f8e \
  --evm-event-index 0 \
  --target staging-settings

Solana log trigger

Solana log triggers require a transaction signature and event index to fetch a specific event from Devnet or Mainnet. Unlike EVM log triggers, there is no listen mode for Solana — you always provide a signature for a transaction that already emitted the event.

Interactive mode:

When you select a Solana log trigger, the simulator prompts you for:

  1. Transaction signature (base58, e.g., c8ifuihaPd2erDuQvees1s2o8ikFmZuNF7WQE63PPGG2SXHZk5vXrHfe7nm4cj4fo7cE3Aq48ksMjP6ugPxAhqn)
  2. Event index (0-based index among the program's events in that transaction, e.g., 0)

The simulator fetches the transaction from the configured RPC, parses its events, and passes the selected one to your workflow.

Non-interactive mode:

Use the --solana-tx-sig and --solana-event-index flags:

cre workflow simulate my-workflow \
  --non-interactive \
  --trigger-index 0 \
  --solana-tx-sig c8ifuihaPd2erDuQvees1s2o8ikFmZuNF7WQE63PPGG2SXHZk5vXrHfe7nm4cj4fo7cE3Aq48ksMjP6ugPxAhqn \
  --solana-event-index 0 \
  --target staging-settings

Additional flags

--engine-logs (-g)

Enables detailed engine logging for debugging purposes. This shows internal logs from the workflow execution engine.

cre workflow simulate my-workflow --engine-logs --target staging-settings

--target (-T)

Specifies which target environment to use from your configuration files. This determines which RPC URLs, settings, and secrets are loaded.

cre workflow simulate my-workflow --target staging-settings

--verbose (-v)

Enables debug-level logging for the CLI itself (not the workflow). Useful for troubleshooting CLI issues.

cre workflow simulate my-workflow --verbose --target staging-settings

Understanding the output

When you run a simulation, you'll see the following output:

1. Compilation confirmation

Workflow compiled

This indicates your workflow was successfully compiled to WASM.

2. Trigger selection menu (interactive mode only)

If your workflow has multiple triggers, you'll see a menu:

🚀 Workflow simulation ready. Please select a trigger:
1. cron-trigger@1.0.0 Trigger
2. http-trigger@1.0.0-alpha Trigger
3. evm:ChainSelector:16015286601757825753@1.0.0 LogTrigger

Enter your choice (1-3):

If your workflow has only one trigger, it will run automatically without this prompt.

3. User logs

Logs from your workflow code (e.g., logger.Info() calls) appear with timestamps:

2025-10-24T19:07:27Z [USER LOG] Running CronTrigger
2025-10-24T19:07:27Z [USER LOG] fetching por url https://api.example.com
2025-10-24T19:07:27Z [USER LOG] ReserveInfo { "totalReserve": 494515082.75 }

4. Final execution result

The simulator displays the value returned by your workflow:

Workflow Simulation Result:
 {
  "result": 47
}

5. Transaction details (if your workflow writes onchain)

If your workflow performs onchain writes, the simulator will show transaction information:

Without --broadcast (dry run):

The transaction is prepared but not sent. You'll see a zero address (0x0000...) as the transaction hash:

2025-10-24T23:01:50Z [USER LOG] Write report transaction succeeded: 0x0000000000000000000000000000000000000000000000000000000000000000

With --broadcast:

The transaction is actually sent to the blockchain. You'll see a real transaction hash:

2025-10-24T17:55:48Z [USER LOG] Write report transaction succeeded: 0x1013abc0b6f345fad15b19a56cabbbaab2a2aa94f81eb3a709058adf18a4f23f

Limitations

While simulation provides high confidence in your workflow's behavior, it has some limitations:

  • Single-node execution: Simulation runs on a single node (your local machine) rather than across a DON. There is no actual consensus or quorum, it is simulated.
  • Manual trigger execution: Time-based triggers (cron) execute immediately when selected, not on a schedule. You must manually initiate each simulation run.
  • Simplified environment: The simulation environment mimics production but is not identical. Some edge cases or network conditions may only appear in a deployed environment.

Despite these limitations, simulation is an essential tool for catching bugs, validating logic, and testing integrations before deploying to production.

Next steps

Get the latest Chainlink content straight to your inbox.