Routine limits and FAQ
Step quotas, definition sizes and retention for routines in the beta, and answers to common questions about durability, retries and triggers.
Limits
| Limit | Value |
|---|---|
Steps per day per organization (routines.steps.daily) | 50,000 |
| Steps per routine | 500, map bodies included |
| Triggers per routine | 20 |
| Map elements | 10,000 per map |
| Map concurrency | 256, 8 by default |
| Map nesting | 3 levels |
| Steps in one map body | 100 |
| Signals buffered per name per run | 16 |
| Retry attempts | 20, the first included |
| Step timeout | Up to 24 hours; 30 seconds by default |
| Definition size | 1 MiB |
| Cron catch-up window | Up to 30 days, a day by default |
| Webhook timestamp tolerance | 30 to 300 seconds |
Going over the daily step quota returns 429 quota_exceeded until the window resets.
Retention
Run history, steps and events: 30 days. Versions stay as long as the routine.
FAQ
standard for most work: effects are durable before the steps after them run, and a crashed run resumes from the journal. ephemeral for short routines an agent calls like a tool and waits on, where losing a run to a crash is acceptable. strict when a step's effect must never repeat, at the cost of two disk commits per effect step.
Durable runs survive process crashes and restarts. They do not survive the loss of the node itself; the beta runs on one node. While the node is down, webhook deliveries queue at the edge and replay in order, and schedules apply their catch-up policy when it returns.
Only failures the callee marks retryable are retried, and only pure and read steps take defaults.retry. A write step needs its own retry; an irreversible step never retries.
A CEL expression hit a missing field or mixed types at run time. Guard optional data with has() and convert numbers explicitly. POST /v1/routines/validate catches syntax and name errors before you publish.
The key that published its active version, with that key's scopes copied at publish time. Revoking the key pauses the routine's triggers.
Not directly: there is no shell step. Use sandboxes/exec@1 with a template for a fresh sandbox or sandbox for an existing one.
Store it in the vault and bind it to a pack action step with connections. It is injected at the egress proxy and never appears in the definition, the run or its logs.