# Simulating Workflows
Source: https://docs.chain.link/cre/guides/operations/simulating-workflows
Last Updated: 2026-10-30

> For the complete documentation index, see [llms.txt](/llms.txt).

Workflow simulation is a local execution environment that **compiles your workflow to [WebAssembly (WASM)](https://webassembly.org)** 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](/cre/guides/workflow/using-triggers/cron-trigger), [HTTP](/cre/guides/workflow/using-triggers/http-trigger/overview), [EVM log](/cre/guides/workflow/using-triggers/evm-log-trigger), or [Solana log](/cre/guides/workflow/using-triggers/solana-log-trigger) triggers.
- **Verify onchain interactions**: Test [read](/cre/guides/workflow/using-evm-client/onchain-read) and [write](/cre/guides/workflow/using-evm-client/onchain-write/overview) operations against real testnets.

## Basic usage

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

**Basic syntax:**

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

**Example:**

```bash
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](#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](/chainlink-platform/creating-an-account?parent=cre) and [Log in with the CLI](/cre/guides/cli/cli-login) for instructions.
- **CRE CLI installed**: You must have the CRE CLI installed on your machine. See [CLI Installation](/cre/getting-started/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](/cre/reference/project-configuration) for setup instructions.
- **Private key**: Set `CRE_ETH_PRIVATE_KEY` in your `.env` file if your workflow performs onchain writes.

> **TIP: New to CRE?**
>
> If these prerequisites seem overwhelming, we strongly recommend starting with the [Getting Started
> guide](/cre/getting-started/overview). It walks you through setting up your first project, configuring your
> environment, and running your first simulation step by step.

## Interactive vs non-interactive modes

### Interactive mode (default)

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

**Example:**

```bash
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](#trigger-specific-configuration))

**Example:**

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

> **TIP: Understanding trigger-index**
>
> The `--trigger-index` flag selects **which handler** in your workflow to execute. Handlers are created in your
> `InitWorkflow` function using `cre.Handler()`, where [each handler connects a trigger to a callback
> function](/cre/key-terms#handler). If your workflow has only one handler, use `--trigger-index 0`. If you have
> multiple handlers (e.g., one for an HTTP trigger and one for an EVM log trigger), use `0` for the first, `1` for the
> second, etc., based on their order in your code.

## 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.

```bash
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](/cre/service-quotas#http-trigger): 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](/cre/guides/operations/understanding-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`.

> **NOTE: Using --listen with --non-interactive**
>
> If you combine `--listen` with `--non-interactive` for an HTTP trigger, you must also pass `--http-payload`. The
> simulator runs that payload first, then keeps listening for more requests.

See [Testing HTTP Triggers in Simulation](/cre/guides/workflow/using-triggers/http-trigger/testing-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`](/cre/reference/cli/workflow#cre-workflow-build), then pass it to `simulate`. Your `workflow.yaml` stays unchanged.
- **Custom build**: Convert the workflow with [`cre workflow custom-build`](/cre/guides/operations/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`:**

```bash
# 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.

> **TIP: Same binary for simulate, hash, and deploy**
>
> The `--wasm` flag is also available on [`cre workflow hash`](/cre/reference/cli/workflow#cre-workflow-hash) and [`cre
>   workflow deploy`](/cre/reference/cli/workflow#cre-workflow-deploy). Building once and passing the same binary to each
> command ensures you simulate the exact artifact you deploy. The binary hash printed during simulation matches the hash
> printed by `cre workflow build`.

## 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:

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

> **CAUTION: Broadcast requires a funded wallet**
>
> When using `--broadcast`, your wallet (specified by `CRE_ETH_PRIVATE_KEY` in `.env`) must be funded with the native
> token of the chain you're writing to (e.g., Sepolia ETH for Ethereum Sepolia testnet). Visit
> [faucets.chain.link](https://faucets.chain.link) to get your testnet tokens.

> **CAUTION: Solana simulation always requires CRE\_ETH\_PRIVATE\_KEY**
>
> For Solana workflows, `CRE_ETH_PRIVATE_KEY` is required even for dry-run simulation (without `--broadcast`). The CLI
> uses it for workflow owner derivation regardless of chain family. Set any valid EVM private key in your `.env` — it
> is not used for the Solana transaction itself. You also need `CRE_SOLANA_PRIVATE_KEY` for the transmitter account; see
> [Writing to Solana](/cre/guides/workflow/using-solana-client/onchain-write-ts) for setup details.

**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](/cre/guides/workflow/using-triggers/cron-trigger) do not require additional configuration. When selected, they execute immediately.

> **NOTE: Single trigger workflows**
>
> If your workflow has only one trigger, the simulator will automatically run it without prompting you to select.

**Interactive example:**

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

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

**Non-interactive example:**

```bash
# 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
```

> **TIP: Finding your trigger index**
>
> The `--trigger-index` is 0-based and corresponds to the order in which triggers are defined in your workflow code. The
> first trigger is index `0`, the second is `1`, and so on. If you're unsure which index to use, run the simulator in
> interactive mode first to see the list of triggers.

### HTTP trigger

[HTTP triggers](/cre/guides/workflow/using-triggers/http-trigger/configuration) 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:**

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

> **TIP: Detailed HTTP trigger testing guide**
>
> For a complete guide with workflow examples, test scenarios, and expected output, see [Testing HTTP Triggers in
> Simulation](/cre/guides/workflow/using-triggers/http-trigger/testing-in-simulation).

### EVM log trigger

[EVM log triggers](/cre/guides/workflow/using-triggers/evm-log-trigger) 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:

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

> **TIP: Understanding the two different indexes**
>
> **Two separate concepts:**
>
> - **`--trigger-index`** selects **which handler** in your workflow to run (e.g., if the
>   handler with an EVM log trigger is the third handler defined, use `--trigger-index 2`)
> - **`--evm-event-index`**
>   specifies **which log/event within the transaction** to use for testing (e.g., if the transaction emitted 3 events and
>   you want the first one, use `--evm-event-index 0`)
>
> These are completely independent: one selects your workflow's
> handler to execute, the other selects which event data from the blockchain to test with.

### Solana log trigger

[Solana log triggers](/cre/guides/workflow/using-triggers/solana-log-trigger) 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:

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

> **NOTE: Where to get a transaction signature**
>
> You need a Devnet (or Mainnet) transaction that already emitted the event you want to test with. If you are following
> the [Solana Log Trigger guide](/cre/guides/workflow/using-triggers/solana-log-trigger), broadcast a transaction with
> the [Writing to Solana guide](/cre/guides/workflow/using-solana-client/onchain-write) first (`cre workflow simulate
>   ... --broadcast`), then reuse its `txSignature`.

> **CAUTION: CRE\_SOLANA\_PRIVATE\_KEY is still required**
>
> Solana simulation requires a funded `CRE_SOLANA_PRIVATE_KEY` for every run, including a log-trigger-only dry run that
> never submits a transaction. See [Writing to Solana: Step
> 4](/cre/guides/workflow/using-solana-client/onchain-write#step-4-run-the-simulation) for how to generate and fund one.

## Additional flags

### `--engine-logs` (`-g`)

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

```bash
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.

```bash
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.

```bash
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

- **Test against production limits**: Use the `--limits` flag to enforce production quotas during simulation. See [Testing Production Limits](/cre/guides/operations/understanding-limits).
- **Deploy your workflow**: Once you're confident your workflow works correctly, see [Deploying Workflows](/cre/guides/operations/deploying-workflows).
- **CLI reference**: For a complete list of flags and options, see the [CLI Workflow Commands reference](/cre/reference/cli/workflow/).