Docs / Strand / advanced/limits
Limits & Quotas
Strand enforces resource limits at multiple layers to ensure platform stability and fair usage across accounts. All limits are generous and designed to support real production workflows; they only restrict behavior that could destabilize the platform.
Execution Limits#
These limits protect the workflow engine during execution.
| Limit | Value | Description |
|---|---|---|
| Workflow timeout | 10 minutes | Maximum wall-clock time for a single workflow run |
| Node request timeout | 5 minutes | Ceiling on a single node's timeout, whatever you configure |
| Node retry attempts | 5 | Ceiling on retry.max_attempts, reduced further so attempts × timeout fits the workflow timeout |
| Max nodes per workflow | 1,000 | Maximum number of nodes in a workflow definition |
| Max edges per workflow | 2,000 | Maximum number of edges (connections) in a workflow |
| Max graph depth | 100 | Maximum sequential depth (longest chain of nodes) |
| Max outgoing edges per node | 50 | Maximum branches leaving a single node |
| forEach items | 1,000 default (configurable per node, hard max 10,000) | Maximum items processed in a single forEach loop |
| Node execution cap | 100 per node per run | Prevents infinite loops: a single node can execute at most 100 times |
| Step output size (per event) | 10 MB | Maximum size of a single output event |
| Total output size (per run) | 100 MB | Maximum cumulative output across all steps in a run |
| Nested workflow depth | 10 | Maximum depth for nested flow.call invocations |
| JSON nesting depth | 20 levels | Maximum depth for any JSON payload (prevents CPU exhaustion) |
The per-event 10 MB and per-run 100 MB output caps are fixed engine limits and apply to every plan. They are separate from the Python snippet output limit (1–10 MB by plan), which only governs what a Python snippet can return; see Python Snippet Limits.
Node Timeouts and Retries#
A node's timeout defaults to 30 seconds and can be raised, but not past 5 minutes. Retries are capped at 5 attempts, and reduced further so that attempts × timeout still fits inside the 10-minute workflow timeout — a single node can never outlive the run it belongs to.
When a run is close to its deadline, a node's timeout is trimmed to whatever time is left, so the workflow timeout is enforced rather than merely advertised.
These are hard engine limits on every plan, and they exist because workflow execution slots are shared. A node that blocks holds a slot that other accounts are waiting for, so an unbounded timeout would let one workflow degrade everyone. If you configure something above a ceiling it is capped rather than rejected, and the capping is logged in your run output.
If you genuinely need to wait longer than five minutes on an external system, poll it instead: have the node return quickly and use a schedule or a webhook callback to continue. That keeps the wait off a worker slot.
forEach Limits#
The forEach node processes items concurrently. The default cap is 1,000 items per loop and can be configured per node, but never above the hard ceiling of 10,000 items. If your workflow receives an array larger than the configured limit, it will be truncated. This prevents a single event from spawning an unbounded number of child executions.
Plan-Based Limits#
Workflows, monthly runs, concurrency, and resource quotas (connectors, vault entries, etc.) scale with your plan. See tendrl.com/pricing for current limits.
Device-triggered runs are never billed. Runs started by a Contact device event (a tagged message matching an exposed workflow) don't count against your monthly run quota; they're tracked and shown separately in your usage. Quotas meter the runs you start (manual, scheduled, API); your devices can't spend your quota. Compute-unit limits and the per-workflow trigger rate limit still apply to all runs.
Rate Limits#
API rate limits protect against automated abuse. They are keyed per account (not per IP), so multiple team members sharing an account share the same limit.
| Endpoint type | Limit | Description |
|---|---|---|
| Write endpoints (POST/PUT/DELETE) | 30 per minute | Applies to connector, workflow, vault, subscription, configuration, connection, and function creation/update/delete |
| Run a workflow (POST /api/workflows/{id}/run) | 60 per minute | Triggering one specific workflow over HTTP |
| Contact event trigger | 50 workflows per event | Maximum workflows that can be triggered by a single Contact event |
Rate limits apply per account and reset every minute.
Queue Limits#
Backpressure controls prevent the workflow queue from being overwhelmed.
| Limit | Value | Description |
|---|---|---|
| Global queue depth | 10,000 | Maximum total items across the workflow queue |
| Per-account queue depth | 500 | Maximum queued runs for a single account |
| Queue item TTL | 1 hour | Automatic cleanup for stale queue counters |
When the queue is full, new trigger requests receive a 503 Service Unavailable response with a clear message. Existing runs continue processing normally; the backpressure only prevents new runs from being enqueued.
Python Snippet Limits#
Python code snippets execute in a security sandbox with resource limits that scale with your plan (code size, execution time, memory, output size, and temporary file size). See Python Snippet Resource Limits for the per-plan table and Python Snippet Security for the execution sandbox.
Cloud Connector Timeouts#
All cloud connector SDK calls (AWS, Azure, GCP) use explicit timeouts to prevent worker threads from hanging on network issues.
| Timeout | Value | Description |
|---|---|---|
| Connection timeout | 10 seconds | TCP connection establishment |
| Read timeout | 30 seconds | Waiting for response data |
| Max retries (AWS) | 2 | Automatic retry on transient failures |
These timeouts ensure that a single slow cloud API call cannot indefinitely block a worker thread.
What Happens When You Hit a Limit#
| Limit type | HTTP status | Error field | What to do |
|---|---|---|---|
| Plan quota (workflows, connectors, etc.) | 403 |
error: "...limit reached" |
Delete unused resources or upgrade your plan at tendrl.com/pricing |
| Rate limit | 429 |
Too Many Requests |
Wait and retry (limits reset every minute) |
| Queue full | 503 |
Service Unavailable |
Wait for existing runs to complete |
| Validation error (JSON depth, payload size) | 422 |
Validation Error |
Reduce payload complexity or size |
| Execution timeout | Run status: failed |
error: "Workflow execution timed out" |
Optimize your workflow or break it into smaller pieces |
All error responses include a descriptive message explaining what limit was hit and how to resolve it. Plan-based limits include the current usage, the limit, and the plan name so you can make informed decisions about upgrading.
Adjusting Limits#
- Execution limits: forEach batch size is configurable per node (up to the hard max of 10,000). Concurrency is set by your plan tier; see Max Workflow Concurrency.
- Need higher limits?: Visit tendrl.com/pricing or contact support.
Tendrl