lua test applies the limit: yes when the CLI, the compiler, or the API a local call reaches enforces it; no when only the deployed runtime does, so a local run can exceed it; n/a when the limit has no local path. If you hit a limit that is not listed, report it to [email protected].
Verified against lua-cli 3.33.0.
Execution time
| Limit | Value | Notes | Enforced locally by lua test? |
|---|---|---|---|
Tool execute | 180 s | 300 s when the tool runs from a trigger; not retried | No |
Webhook execute | 180 s | A subscribed event gets 3 attempts, 60 s apart; a direct request is not retried | No |
Tool or skill condition | 30 s | n/a; condition is never evaluated locally | |
| Preprocessor, postprocessor | 180 s | No | |
| Model resolver | 5 s | n/a | |
| Trigger slots | 15 s for all slots together | n/a | |
Job timeout | 1 to 600 s | Default 300 s (LuaJob); a timed-out attempt counts as failed | No; the range is checked when the job is constructed |
| Workflow code or tool step | 300 s default | Worker tier maximum 600 s; a timed-out attempt is retried under retry | Yes |
| Workflow agent step | 600 s default | n/a; agent steps are faked offline | |
| Workflow Job-tier step | 3,600 s default | Maximum 86,400 s, run in segments of at most 14,400 s | No; the caps are checked at compile |
Workflow ctx.exec command | 600 s default | No | |
| Integration passthrough request | 60 s | Integrations.passthrough | Yes; the local call reaches the same API |
| MCP server call | 60 s | One retry for a read-shaped tool on a timeout | n/a |
| Device command | 30 s default | Set per command | n/a |
Device trigger execute | 10 min | Platform default for event handlers; delivered at least once, 3 attempts 60 s apart | n/a |
Payloads and sizes
| Limit | Value | Notes | Enforced locally by lua test? |
|---|---|---|---|
| Webhook event payload | 50,000 characters | Over the cap, a subscribed event runs once, without retries | No |
| Trigger payload | 50,000 characters | Tool result returned through a trigger: 4,000 characters | n/a |
| Tool result passed to the model | 300,000 characters | No | |
| Persona | 16,000 characters | n/a | |
Chat attachment (lua chat -m "@file") | 10 MB per file | n/a | |
| Document conversion (files sent in chat) | 100 MB per file | n/a | |
CDN upload (CDN) | 100 MB per file | Yes; the local call reaches the same service | |
| Log message field | 256 KB | Longer messages end with [truncated; original length <n>] | No |
Job heap before execute | 128 MB | Memory limit exceeded before execution; jobs only (execution contexts) | No |
Data and commerce
| Limit | Value | Notes | Enforced locally by lua test? |
|---|---|---|---|
Data.get page size | 100 entries | Default 10 | Yes; clamped by the API the local call reaches |
Data.search results | 20 entries | Larger values are clamped | Yes; clamped by the API the local call reaches |
Data.search scoreThreshold | 0 to 1 | Yes | |
Products.get page size | 100 products | Default 10 | Yes; clamped by the API the local call reaches |
Inbox list page size | 100 items | n/a |
Jobs
| Limit | Value | Notes | Enforced locally by lua test? |
|---|---|---|---|
| Interval schedule | 60 s minimum | Whole minutes only (a multiple of 60) | No; checked at push |
timeout | 1 to 600 s | Default 300 s | Yes; the LuaJob constructor throws |
| Retry attempts | 10 at most | Whatever maxAttempts says; a timed-out attempt counts (jobs) | No |
| Retry wait | backoffSeconds, default 60 | Fixed before every retry; no jitter | No |
Workflows
| Limit | Value | Notes | Enforced locally by lua test? |
|---|---|---|---|
| Nodes per graph | 200 | Child-run nesting depth 3; parallel arms 2 to 16 | Yes; at compile |
foreach items | 20,000 maximum | Default 256; concurrency 4 default, 16 maximum; a longer list fails, never truncated | Yes; at compile (a script-form run allows 4,096 locally) |
loop iterations | 100 default | n/a | |
| Retry attempts | 1 to 20 | Backoff capped at 3,600 s, which is also the default | Yes; attempts at compile, the backoff cap only deployed |
budget.maxDurationSeconds | 60 to 2,592,000 s | 1 minute to 30 days | No; checked at push |
| Approval or signal wait | 168 h default | timeoutHours up to 720 | n/a |
| Signal payload | 64 KB | 256 unconsumed signals per run | No |
Run state (ctx.state) | 64 KB | No | |
| Approval payload | 5 MB | n/a; approvals are pre-answered offline | |
| Step output | 256 KB inline; 8 MB maximum | Larger outputs are stored aside; a script-form step over 256 KB fails | Script form yes; graph form no |
| Upstream step results carried into a step | 4 MiB together | Larger entries are replaced with STEP_RESULT_TOO_LARGE | No |
once() result | 32 KB | EFFECT_SETTLE_FAILED | No |
Step log() | 1,000 entries per attempt, 1,024 characters each | Script form: the count only | |
ctx.exec output | 1 MB per stream | stdout and stderr each | No |
| Environment overlay | 64 keys, 4 KB per value | lua workflows env-overlay | n/a |
| Script-form workflow pushed from code | 256 KB | Script step() timeout at most 600 s | Yes; at compile |
lua workflows resolve-step --output | 262,144 bytes serialized | 413 OUTPUT_TOO_LARGE from the platform, not the CLI | n/a |
| Workflow starts per chat turn | 3 | n/a | |
| REST calls per user per minute | start 30, compose 20, mutate 60, read 600, batch 5 | Workflows REST | n/a |
Devices
| Limit | Value | Notes | Enforced locally by lua test? |
|---|---|---|---|
| Message payload | 1 MB | n/a | |
| Commands per device | 128 | Also the maximum device tools per agent | n/a |
| Command input schema | 4 KB | n/a | |
| Command name | 64 characters | Lowercase letters, digits, underscores; starts with a letter | n/a |
| Device triggers | 10 per second per agent | RATE_LIMITED on trigger_error; over MQTT the message is Exceeded 10 triggers/s | n/a |
| Trigger handler time limit | 10 min | Platform default for event handlers; 3 attempts 60 s apart, same triggerId | n/a |
| Stored command list | 24 h after connect | Self-describing devices only; heartbeats don’t extend it | n/a |
| Failed handshakes | 5 rejected credentials per 60 s | Per device and credential; then RATE_LIMITED with retryAfterMs 600000 for 10 min | n/a |
| Device CDN upload | 100 MB | One file per request | n/a |
| In-flight commands | 100 per agent | n/a | |
| Error text in a command response | 4 KB | n/a |
Channels
| Limit | Value | Notes | Enforced locally by lua test? |
|---|---|---|---|
| Email attachments | 28 MB per message | All attachments together | n/a |
| Teams attachment | 25 MB | n/a | |
| iMessage media | 25 MB | n/a | |
| iMessage recipients | 10 on the shared tier | No cap on a dedicated tier | n/a |
| Slack message | 50 blocks | 3,000 characters per section, 75 per button label, 2,000 per button value | n/a |
| RCS message | 3,072 characters | Card title 200, card text 2,000, 11 suggestions of 25 characters, 10 carousel cards | n/a |
| RCS bulk capability check | 500 to 10,000 numbers | n/a | |
| MessageBird message | 3 images; 3 buttons of 20 characters; 10 list rows | 2 send retries | n/a |
| WhatsApp carousel card body parameter | 135 characters | n/a | |
| Phone number search | 50 results | n/a | |
| SIP trunk | 16 ACL entries; 200 digest users | Username 5 to 32 characters | n/a |
Meeting memory lastN | 3 default, 10 maximum | n/a | |
| Voice transcription upload | 64 MB | n/a | |
| Inbound messages coalesced into one turn | 10 default | Per-agent maxBatchMessages; exercise it with lua chat -b | n/a |
Logs, backups, and the CLI
| Limit | Value | Notes | Enforced locally by lua test? |
|---|---|---|---|
lua logs --limit | 100 | Default 20 | n/a |
lua triggers logs --limit | 200 | Default 20; executions are kept for 90 days | n/a |
lua jobs history | last 20 executions | n/a | |
lua workflows job-logs --tail | 1 to 2,000 lines | Default 200 | n/a |
lua source list | 50 versions | --all for the full history | n/a |
| Source backup | 5,000 files, 256 KB per file | Larger files are not backed up | n/a |
| Sign-in code | 6 digits, 3 attempts | lua auth configure --email | n/a |
See also
- Execution contexts — what runs where, and the constraints inside a sandboxed function
- Test an agent before you release — run each primitive locally, then confirm it in the sandbox and in production
- Read logs and debug an agent — finding a truncated or failed run
- Errors and exit codes — the CLI’s own failure classes

