Back to Activepieces

Production Setup

docs/install/configure-operate/production-setup.mdx

0.86.35.2 KB
Original Source

This is the production setup we recommend. It is sized from a single number — your peak concurrent flows — and everything else follows from there.

What it looks like

One flow per worker. A small fleet of those. A thin tier of apps in front. Managed Postgres, Redis, and S3 behind — all in the same region.

ComponentSize eachHow many
Worker0.5 vCPU / 1 GB, concurrency 1one per concurrent flow
App1 vCPU / 2 GBone per ten workers
Postgres2 vCPU / 4 GB, managedone, grows with the fleet
Redis1 vCPU / 1 GB, managedone
Object storage (S3)same region, signed URLs onrequired

S3 is a hard requirement, not a nice-to-have: without it, every flow bundle and piece archive funnels through the app tier and the throughput numbers below no longer hold. (Walkthrough: S3 Storage.)

Copy this — it's the exact configuration the benchmark below was measured on:

bash
AP_WORKER_CONCURRENCY=1
AP_REUSE_SANDBOX=true
AP_EXECUTION_MODE=SANDBOX_CODE_ONLY
AP_FILE_STORAGE_LOCATION=S3
AP_S3_USE_SIGNED_URLS=true
<Note> On [Separate Workers](./separate-workers), the execution vars (`AP_WORKER_CONCURRENCY`, `AP_REUSE_SANDBOX`, `AP_EXECUTION_MODE`) go on the **worker** containers and the S3 vars on the **app** containers. Running a single container for both (`AP_CONTAINER_TYPE=WORKER_AND_APP`, the default)? Set them all on it. </Note>

Sizing

A concurrency-1 worker is busy for a flow's whole duration (up to 10 min), so size by concurrent flows, not trigger rate:

workers = peak concurrent flows
apps    = ceil(workers / 10)

At 50 concurrent flows: 50 workers (25 vCPU / 50 GB) + 5 apps (5 vCPU / 5 GB). Overflow queues in Redis and drains as slots free.

<Tip> Size **statically for peak** — autoscaling's boot and scheduling lag can't defend the 30 s sync-webhook budget. A pre-sized fleet keeps a slot warm and waiting. Measured scale-up and drain numbers: [Autoscaling](../architecture/autoscaling). </Tip>

And it scales with your fleet:

Full methodology and the ratio comparison: Benchmark.

Limits

LimitDefaultEnv var
Flow run timeout600 sAP_FLOW_TIMEOUT_SECONDS
Sync webhook response30 sAP_WEBHOOK_TIMEOUT_SECONDS
Max webhook payload25 MBAP_MAX_WEBHOOK_PAYLOAD_SIZE_MB
Step file size25 MBAP_MAX_FILE_SIZE_MB
Flow run log size50 MBAP_MAX_FLOW_RUN_LOG_SIZE_MB

The complete table lives in Limits.

<Note> Need to reserve dedicated capacity for specific tenants? See [Worker Groups](./worker-groups). </Note>

Coming from a single combined container (AP_CONTAINER_TYPE=WORKER_AND_APP, the default — one image running the API and an embedded worker)? This is the path to a split app tier, a concurrency-1 worker tier, and S3. Apply it in a lower environment first, validate, then promote to production. Postgres and Redis don't change — workers never touch them; only the app does.

<Steps> <Step title="Split app and worker"> Same image, two roles selected by `AP_CONTAINER_TYPE`:
  • Existing container → app. Set AP_CONTAINER_TYPE=APP. It stops pulling flows and only serves the API and UI, so heavy runs can no longer slow the interface.
  • New worker container. Run the same image with three env vars — nothing else:
    bash
    AP_CONTAINER_TYPE=WORKER
    AP_FRONTEND_URL=https://your-instance-url
    AP_WORKER_TOKEN=<generated token>
    

Workers hold no Redis or database credentials — they reach the app only over AP_FRONTEND_URL. Generate the token and see the full walkthrough on Separate Workers. </Step> <Step title="Reshape the worker to one flow at a time"> A concurrency-1 worker runs a single flow and is sized small; scale throughput by adding replicas, not by widening one container. Keep total slots constant: slots = containers × concurrency.

bash
AP_WORKER_CONCURRENCY=1
AP_REUSE_SANDBOX=true
AP_EXECUTION_MODE=SANDBOX_CODE_ONLY
BeforeAfter
Per worker~2.5 vCPU / 5 GB, concurrency 50.5 vCPU / 1 GB, concurrency 1
For 50 slots10 workers50 workers

On Worker Groups, keep AP_EXECUTION_MODE=SANDBOX_PROCESS; code-only mode is rejected for grouped workers.

Not ready to reshape? Leave AP_WORKER_CONCURRENCY=5 and size each worker ~5× (≈5 GB); the split and S3 still stand on their own. </Step> <Step title="Enable S3"> Set on the app:

bash
AP_FILE_STORAGE_LOCATION=S3
AP_S3_USE_SIGNED_URLS=true

With signed URLs on, file bytes flow directly between the worker/browser and S3 instead of through the app. Keep the bucket in the same region as your workers. Full env var list (bucket, keys, region): S3 Storage. </Step> </Steps>