Limits And Recovery
Canonical runtime and payload limits for public flow authoring, plus recovery actions for common limit failures.
Quick Answer
Design flows to stay within hard limits, and prefer templates/persistence/chunking before raising payload size in runtime paths.
Core Flow Limits
| Limit | Value | Notes |
|---|---|---|
| Max flow payload size | 150 KB | Definition map only; excludes template/function bodies. |
| Max steps per flow | 50 | Total declared steps in a flow. |
Max flow/call-flow nesting depth | 5 | Child-flow nesting guardrail. |
| Max templates total size | 1 MB | Aggregate template content budget. |
| Max functions total size | 1 MB | Aggregate function content budget. |
| Effective package budget | ~2.1 MB | Combined payload + templates + functions. |
Runtime Limits Per Run
| Limit | Value | Notes |
|---|---|---|
| Max step executions | 10000 | Per run execution ceiling. Includes configured tool calls dispatched by :agent and execute-mode :llm steps. |
| Max HTTP requests | 50 | Per run, across HTTP steps. |
| Max tracked LLM tokens per run (platform-managed keys) | 100000 | Accounting limit for platform-managed keys. |
Platform-managed :max-tokens clamp per LLM call | 10000 | Applied only for platform-managed keys. |
User-provided LLM keys :max-tokens clamp | Not clamped by platform | Provider/account limits still apply. |
| Max workflow duration | 30 days | Hard run duration cap. |
| Max child workflow invocations | 60 | flow/call-flow invocations and async :fanout child runs per root run. |
| Max fanout step executions | 5 | Total :fanout step executions per run. |
| Max fanout total items | 100 | Total items across all :fanout steps in one run. |
Fanout And Child-Workflow Guardrails
| Guardrail | Value | Notes |
|---|---|---|
| Max fanout width | 25 | Max items in one :fanout step. |
Max :on-event emissions | 500 | Per :http step attempt; streamed SSE event emissions past the cap are suppressed and counted. |
| Max async child fanout concurrency | 20 | :max-concurrency must be at most 20; validation rejects larger values. |
| Async fanout item type | :call-flow or :agent | All items in async mode must use the same child workflow item mode. |
| Mixed fanout modes | Not allowed | Do not mix legacy step items, :call-flow items, and :agent items in one :fanout. |
| Nested fanout items | Not allowed | :fanout items cannot themselves be :fanout. |
| Nested async child fanout depth | 1 | Descendant async child fanout is rejected. |
| Child start confirmation | Required | Parent waits for child start confirmation before treating spawn as successful. |
Wait And Approval Limits
| Limit | Value | Notes |
|---|---|---|
| Default wait timeout | 24h | Applies when timeout is omitted. |
| Max wait timeout | 30 days | Hard cap for wait duration. |
| Checkpoint timeout default | 24h | Review checkpoint timeout can be set up to 30 days. |
Polling Limits (flow/poll)
| Limit / Rule | Value | Notes |
|---|---|---|
| Max poll timeout | 1h | Hard timeout ceiling for flow/poll. |
| Max poll attempts | 100 | Hard attempt ceiling for flow/poll. |
| Required bound | At least one of :timeout or :max-attempts | Unbounded polling is rejected. |
| Required condition + backoff validation | :return-on required | Backoff shape is validated (for example :linear requires :step). |
| Terminal provider outcomes | Include success and failure statuses in :return-on, then branch on the result | Stop polling when the remote actor has finished and prevent terminal failures from being recorded as success. |
External Actor Cost Boundary
flow/poll limits the Breyta orchestration loop only. It does not impose a
limit on work already accepted by a third-party actor or provider. Use these
controls together:
| Control | What it limits | What it does not guarantee |
|---|---|---|
| Query/partition count | Number of provider requests started by the flow. | That one provider request produces only one bounded run. |
Provider item limit (maxPosts, limit, maxItems) | Provider-specific requested output size. | A universal cap on actor events, pagination, or billing. |
| Provider run timeout/quota | Provider-side execution where supported. | That the provider exposes the same semantics for every actor. |
flow/poll :timeout / :max-attempts | Breyta status checks and waiting time. | Cancellation of a still-running remote actor. |
| Provider cancellation endpoint | Remote work after the flow detects timeout/error. | Cleanup when the provider has no cancellation surface. |
For high-volume searches, run a small probe first, record the remote run id,
inspect actual events/items and cost, then scale queries and item limits in
stages. If a poll ends before the actor is terminal, cancel it when possible and
do not blindly start a second run.
Step Result And Persistence Limits
| Limit | Value | Notes |
|---|---|---|
| Inline result threshold | 512 KB | Results above this should usually use :persist. |
| Max step result size | 1 MB | Hard per-step output cap. |
| DB result max bytes | 1 MB | Cap for database step result payload bytes. |
| DB result max rows | 5000 | Cap for row count returned by DB steps. |
| Code step input max | 1 MB | Hard cap on :function step :input. |
| Notify payload max | 1 MB | Hard cap for notify payload body. |
| Authoring recommendation | Prefer :persist for unknown/growing outputs | Many real flows exceed inline limits quickly. |
Webhook And Ref Loading Limits
| Limit | Value | Notes |
|---|---|---|
| Webhook payload max | 50 MB | General webhook body size ceiling. |
| Signed multipart webhook payload max | 5 MB | Applies to signed multipart uploads. |
| Raw MIME webhook payload max | 50 MB | Raw MIME ingestion ceiling. |
| Ref load into LLM content | 100 KB | Ref content cap when injected into LLM fields. |
| Ref load into code step | 1 MB | Ref content cap for code step loading. |
| Ref load into HTTP body | 10 MB retained / 20 MB ephemeral tier | Tier-dependent HTTP body ref loading limit. |
| Persist write cap | 50 MB retained / 4 GB ephemeral tier | Tier-dependent blob persistence write limit. |
API Request Validation Limits
JSON request bodies sent to the flows API (CLI commands, connections call,
manual run inputs, ...) pass a generic bounded-payload check before the
handler runs. Violations return HTTP 400 with violation set to the failed
bound (for example max-string-length with at: map-value).
Exemptions: native connection webhooks skip JSON parsing entirely and are
bounded only by the webhook payload caps above, and flowLiteral/flow
command arguments are excluded from these checks (flow definitions have their
own dedicated size limits, listed under Core Flow Limits).
| Limit | Value | Notes |
|---|---|---|
| Max nesting depth | 8 | Webhook/event ingress and dashboard apply allow 10. |
| Max total nodes | 20000 | Counts every key, value, and collection item. |
| Max collection size | 1000 | Per map/vector/set. |
| Max string length | 100000 chars | Per single string value (including map values). |
Max string length, connections call | 6000000 chars (~6 MB) | POST /api/connections/:id/call replays full outbound request bodies, so a single string value may be much larger. The whole request must still fit the ~8 MiB transport body cap. |
Recovery: for oversized payloads on ordinary endpoints, persist the content as
a resource and pass a ref instead of inlining it, or split the request. To
replay a large HTTP request against a provider (for example to read a 4xx
error body), use connections call, which accepts string values up to ~6 MB.
Config Warning Thresholds
| Threshold | Behavior | Recommendation |
|---|---|---|
| ~1 KB per step payload | Non-blocking warning starts around this size | Move large literals into templates. |
Failure Recovery Patterns
When you hit size/limit validation errors, apply these patterns first:
| Validation error | First recovery actions |
|---|---|
Flow payload too large | Move large inline content into :templates and :functions.Replace large literals in :flow with template/function refs. |
Payload contains an overly long string / Payload is too large (API validation) | Persist the content as a resource and pass a ref instead of inlining it. Split the request into smaller payloads. For replaying large HTTP requests against a provider, use connections call (~6 MB per string value). |
Result too large / Query result too large / DB row limit exceeded | Paginate (LIMIT, cursor loops).Aggregate/filter in database first. Persist artifacts and pass refs instead of full payloads. |
Blob reference too large for ... | Reduce blob size before loading it into a step. For user downloads, return signed links instead of loading full content into flow memory. |
Code step :input too large | Pass compact subsets into code steps. Move heavy processing to data layer or external compute. Orchestrate in smaller batches. |
Fanout width exceeds limit / fanout max concurrency exceeded / max fanout total items exceeded | Reduce batch size or requested concurrency. Split work into multiple parent runs or stages. Keep one :fanout bounded to independent child workflows. |
child-flows limit exceeded / Nested async child fanout is not allowed | Keep async child fanout at one orchestration depth. Move deeper branching inside a single child flow. Use plain flow/call-flow for descendant orchestration. |
Wait timeout exceeds maximum | Use shorter waits and multi-stage waits. Branch timeout outcomes explicitly ( :fail or :continue). |
flow/poll timeout exceeds limit / flow/poll max attempts exceeded | Reduce timeout and use staged polling (fast first poll, slower secondary poll). Increase interval and use explicit backoff. Prefer webhook/wait-signal patterns when callbacks are supported. |
| Remote actor continues after polling stops | Call the provider cancellation endpoint with the recorded run id when available. Inspect provider terminal state before retrying. Reduce probe size and configure provider-side quotas/timeouts when cancellation is unavailable. |
Recommended Authoring Checklist
| Checklist item | Why |
|---|---|
Add :persist when output size is uncertain | Prevents inline payload overflow as data grows. |
| Use templates for large request/prompt/SQL bodies | Keeps flow payload size stable and reviewable. |
| Keep waits bounded and keyed | Avoids unbounded waits and ambiguous resume paths. |
Design webhook auth explicitly (:auth {:type ...}) | Prevents insecure/default webhook exposure. |
| Test largest expected payload paths, not just tiny happy-path samples | Catches real-world limit failures before production. |