Skip to main content
The execution engine is the core component that processes workflows step-by-step. It handles code execution, piece actions, branching logic, and loops with robust error handling.

Engine Overview

The engine is a separate Node.js process that:
  • Loads flow definitions from the database
  • Executes steps sequentially or in parallel
  • Handles branching (routers) and loops
  • Sandboxes code execution using isolated-vm
  • Manages piece (integration) execution
  • Stores execution results
Location: packages/server/engine/ Entry Point: src/main.ts Executable: dist/packages/engine/main.js
The engine is spawned as a child process by workers, providing isolation and better resource management.

Engine Architecture

Execution Flow

Step-by-Step Process

1

Initialize

Engine receives execution request from worker:
2

Load Flow

Fetch flow version from database:
3

Initialize Context

Create execution context:
4

Execute Steps

Process each step in order:
  • Resolve input variables from context
  • Execute step (code/piece/branch/loop)
  • Store result in context
  • Handle errors with retries
5

Return Result

Return execution result to worker:

Step Executors

Code Executor

Purpose: Execute custom JavaScript/TypeScript code Location: src/lib/handler/code-executor.ts Sandboxing: Uses isolated-vm for security
Sandbox Configuration:
Security Features:
  • Memory Limit: 128MB default (prevents DoS)
  • No File Access: Cannot read/write files
  • No Network: Cannot make HTTP requests (use pieces instead)
  • CPU Timeout: Execution time limits
  • Isolated Heap: Separate V8 heap per execution

Piece Executor

Purpose: Execute integration actions (Slack, Gmail, etc.) Location: src/lib/handler/piece-executor.ts Dynamic Loading: Pieces loaded at runtime
Piece Structure:

Router Executor

Purpose: Conditional branching based on expressions Location: src/lib/handler/router-executor.ts Logic: Evaluates conditions and executes matching branch
Condition Types:
  • Equals: {{trigger.status}} == 'active'
  • Contains: {{trigger.tags}} contains 'urgent'
  • Greater Than: {{trigger.amount}} > 100
  • Exists: {{trigger.email}} exists

Loop Executor

Purpose: Iterate over arrays and execute steps for each item Location: src/lib/handler/loop-executor.ts Execution: Sequential or parallel iteration
Loop Variables:
  • {{loop.item}}: Current item
  • {{loop.index}}: Current index (0-based)
  • {{loop.total}}: Total items

Execution Context

Context Structure

Variable Resolution

Engine resolves {{variable}} syntax:
Resolution Rules:
  • Nested properties: {{trigger.user.email}}
  • Array access: {{trigger.items[0].name}}
  • Step outputs: {{send_email.message_id}}
  • System vars: {{vars.API_KEY}}

Error Handling

Error Types

Errors within a specific step:
Handling:
  • Retry with exponential backoff
  • Continue to error handler step
  • Mark run as failed

Retry Strategy

Retryable Errors:
  • Network timeouts
  • 429 Rate Limit
  • 500 Server Error
  • 503 Service Unavailable
Non-retryable Errors:
  • 400 Bad Request
  • 401 Unauthorized
  • 404 Not Found
  • Code syntax errors

Performance Optimization

Execution Mode

Security: HighPerformance: Moderate (V8 isolate overhead)
Use for: Production, untrusted code

Memory Limits

.env

Timeouts

.env

Caching

.env

Monitoring Execution

Execution Logs

Engine writes detailed logs:

Flow Run Entity

Stored in database:

Metrics

Track engine performance:
  • Execution time: p50, p95, p99
  • Success rate: successful / total
  • Error rate: failed / total
  • Step duration: per step type
  • Memory usage: peak memory per execution

Advanced Features

Child Flows

Execute flows within flows:
Features:
  • Pass data from parent to child
  • Wait for child completion
  • Access child output: {{execute_flow.output}}
  • Fail parent on child failure

Parallel Execution

Not currently supported - steps execute sequentially Workaround: Use loops with async pieces

Step Dependencies

Steps can reference previous step outputs:

Troubleshooting

Symptoms: Flows fail with timeout errorSolutions:
Symptoms: Code steps fail with OOMSolutions:
Symptoms: {{variable}} not resolvingCheck:
  1. Variable exists in context
  2. Correct syntax: {{step.output.field}}
  3. Step executed before reference
Debug:

Next Steps

Workers

Understand worker architecture

Scaling

Scale execution capacity

Architecture

System architecture overview

Environment Variables

Configure engine settings