Skip to main content
This component is responsible for polling jobs from the app, preparing the sandbox, and executing them with the engine.

Jobs

There are three types of jobs:
  • Recurring Jobs: Polling/schedule triggers jobs for active flows.
  • Flow Jobs: Flows that are currently being executed.
  • Webhook Jobs: Webhooks that still need to be ingested, as third-party webhooks can map to multiple flows or need mapping.
This documentation will not discuss how the engine works other than stating that it takes the jobs and produces the output. Please refer to engine for more information.

Sandbox Architecture

The sandbox is a standalone package (@activepieces/sandbox) that manages isolated execution environments for the engine. It consists of the following components:
  • Sandbox Pool: Manages a pool of sandbox instances based on AP_WORKER_CONCURRENCY. Sandboxes can be reused across executions (in trusted modes) or shut down after each use (for full isolation).
  • Sandbox Process: Each sandbox spawns a child process. The process type depends on the execution mode — either a simple fork() or an isolate binary for kernel-level isolation.
  • WebSocket Server: A Socket.IO server (on port 12345) that handles bidirectional communication between the worker and the engine running inside each sandbox. The engine connects with its sandboxId and exchanges operations and results over WebSocket events.

Execution Flow

1

Allocate Sandbox

The worker allocates a sandbox from the pool. If the sandbox is reusable and already running, it is reused directly. If the sandbox generation is stale (e.g., dev pieces changed), it is restarted.
2

Start Sandbox Process

The sandbox spawns a child process (either via fork() or the isolate binary depending on the execution mode). The child process starts the engine and connects back to the worker via WebSocket.
3

Execute Operation

The worker sends the engine operation (e.g., execute flow, execute trigger) over WebSocket. The engine processes it and sends back the result, along with stdout/stderr output.
4

Release Sandbox

After execution completes (or times out), the sandbox is released back to the pool. In non-reusable modes, the sandbox process is shut down before release.

Execution Modes

Sandbox in Activepieces means in which environment the engine will execute the flow. There are four types of sandboxes, each with different trade-offs:
NameSupports NPM in Code PieceRequires Docker to be PrivilegedPerformanceSecure for Multi TenantReusable WorkersEnvironment Variable
V8/Code SandboxingNoFast & LightweightSet AP_EXECUTION_MODE to SANDBOX_CODE_ONLY
No SandboxingNoFast & LightweightSet AP_EXECUTION_MODE to UNSANDBOXED
Kernel Namespaces SandboxingYesSlow & CPU IntensiveSet AP_EXECUTION_MODE to SANDBOX_PROCESS
Combined SandboxingYesMedium & CPU IntensiveSet AP_EXECUTION_MODE to SANDBOX_CODE_AND_PROCESS

No Sandboxing & V8 Sandboxing

The difference between the two modes is in the execution of code pieces. For V8 Sandboxing, we use isolated-vm, which relies on V8 isolation to isolate code pieces. In both modes, the sandbox spawns the engine using a simple Node.js fork() with memory limits. The engine process stays warm and connected via WebSocket, executing operations as they arrive.
1

Prepare Code Pieces

If the code doesn’t exist, it will be built with bun and the necessary npm packages will be prepared, if possible.
2

Install Pieces

Pieces are npm packages, we use bun to install the pieces.
3

Execution

The sandbox allocates a process from the pool. The engine stays running and connected via WebSocket. Each sandbox executes one engine operation at a time and sends back the result upon completion.

Security

In a self-hosted environment, all piece installations are done by the platform admin. It is assumed that the pieces are secure, as they have full access to the machine. Code pieces provided by the end user are isolated using V8, which restricts the user to browser JavaScript instead of Node.js with npm.

Performance

The flow execution is fast as JavaScript can be, although there is overhead in polling from queue and preparing the files the first time the flow gets executed.

Benchmark

TBD

Kernel Namespaces Sandboxing

In this mode, the sandbox uses the isolate binary to run the engine inside kernel namespaces with full filesystem, memory, and CPU isolation.

Prepare the folder

Each flow will have a folder with everything required to execute the flow, which means the engine, code pieces and npms.
1

Prepare Code Pieces

If the code doesn’t exist, it will be compiled and the necessary npm packages will be prepared, if possible.
2

Install Pieces

Pieces are npm packages. If they don’t exist, we use bun to install them.

Execute Flow using Sandbox

The sandbox uses the isolate binary to create an isolated environment with its own namespaces. The prepared folders are mounted as read-only directories inside the sandbox:
  • /root — Engine and common cache
  • /codes — Flow code artifacts
  • /etc — System configuration
  • /node_modules, /pieces — Custom pieces (for dedicated workers)
The isolate binary is invoked with flags for namespace isolation, network sharing, and resource limits:
isolate --dir=/root=<cache> --dir=/codes=<code-cache> --share-net --box-id=<id> --processes --run /usr/bin/node /root/main.js
The engine inside the sandbox connects back to the worker via WebSocket to receive operations and send results.

Security

The flow execution is isolated in its own namespaces, which means pieces run in a separate process with filesystem restrictions. The user can run bash scripts and use the file system safely as it’s limited and will be removed after the execution. In this mode, the user can use any NPM package in their code piece.

Performance

This mode is Slow and CPU Intensive. The reason behind this is the cold boot of Node.js, since each flow execution will require a new Node.js process. The Node.js process consumes a lot of resources and takes some time to compile the code and start executing.

Benchmark

TBD