Timeouts and long-running work
Timeouts and long-running work
Runtype bounds each continuous run of a Flow with wall-clock timeouts. These timeouts limit one active run leg, not the total lifetime of the work. A Flow that pauses durably and resumes gets a fresh budget on each leg, so a job can span hours or days while every individual leg stays inside its limits. This page lists the limits for each entry point and shows how to structure work that takes longer than a single leg.
Timeout limits by entry point
Each entry point accepts timeout overrides in its options object. The following table lists the settings, their defaults, and the accepted ranges:
When a batch or schedule setting is unset, the per-Record execution uses the platform defaults of 5 minutes per step and 15 minutes per Flow. For the interaction between the step, Flow, and whole-agent budgets, and the smaller 30-second default on execute-agent steps, see Debugging flows.
Timeouts bound one run leg, not the whole job
A timeout measures continuous execution, not elapsed calendar time. When a Flow pauses durably (a human approval gate, a wait-until step, or an asynchronous crawl), the pause does not consume the timeout budget. Each resumed leg starts with a fresh, full budget from the original flowTimeoutMs. An approval that sits unanswered for two days does not time out the Flow when someone answers it.
This is the design principle behind every pattern in this page: keep each continuous leg inside its budget, and let pauses, Records, and separate executions carry the work across hours.
Detach an interactive execution from the client request
When POST /v1/dispatch or POST /v1/agents/{id}/execute may outlive the caller’s HTTP or MCP timeout, send Prefer: respond-async. Runtype durably queues the execution and immediately returns 202 Accepted with an execution handle:
Poll GET {statusUrl} with the same account credential while status is queued or running. A terminal response uses completed, failed, or cancelled and includes the result or error. A paused response is actionable rather than poll-progressing: it contains the underlying paused result and pausedReason, and continued polling does not resume it. Complete the required approval or tool-output continuation through the corresponding dispatch or Agent endpoint. Polling the handle is safe; retrying the original execution request may duplicate side effects.
The MCP dispatch, run_flow, and execute_agent tools expose this as async: true. Pass the returned executionId to get_execution_status while it is queued or running; handle a paused result through its continuation endpoint.
A detached Flow can set both options.flowTimeoutMs and options.stepTimeoutMs as high as 1800000 (30 minutes), matching the batch per-Record ceiling. The smaller attached limits remain 15 minutes per Flow and 10 minutes per step. MCP run_flow exposes the same controls as flow_timeout_ms and step_timeout_ms; values above the attached limits require async: true.
The TypeScript SDK exposes the same lifecycle directly:
For a saved Agent, use client.agents.executeAsync(agentId, request) and poll the returned handle the same way. A paused result still requires the corresponding approval or tool-output continuation; polling alone does not resume it.
Generic asynchronous dispatch does not accept inline secrets or an identity_proof, because those live credentials must not be stored in a durable job payload. Store reusable credentials as managed Secrets and reference them with {{secret:NAME}}, or keep a proof-bearing request attached. A saved Claude Managed Agent invoked with a conversationId remains on its native durable lane, which can accept identityProof without persisting the raw token. When Identity Exchange admission is enabled, Runtype verifies the proof before handoff; when admission is disabled, the request accepts and ignores it.
Wait for slow external work with durable pauses
If a step spends most of its time waiting on an external system, use a wait-until step instead of holding a prompt or api-call step open. Configure the poll object with an HTTP request, an intervalMs, a maxAttempts cap, and a success criterion. The Flow parks durably between poll attempts, and each poll attempt is a short, cheap request rather than continuous execution.
Durable pauses have generous bounds:
- A
wait-untilor asynchronouscrawlpause is bounded by a 30-day ceiling. For a long wait, raiseintervalMsrather thanmaxAttempts. - A human approval gate holds for up to 7 days.
Durable pauses require a dispatch surface with durable hosting. For the engine-eligibility details, see Flow validation warnings.
Run long phases as detached subagents
An attached subagent call waits for the child agent to finish, so it is bounded by the parent’s step budget. When a phase needs more time than that, run it detached.
A detached subagent runs as its own execution with its own budget, configurable up to 24 hours through detachedMaxBudgetMs in the agent’s subagentConfig. The spawning call returns a durable run ID immediately and the parent continues. The notify setting controls what happens on completion: none stores the result, narrate posts status into the parent conversation, and react starts a fresh parent turn with the result.
To allow detached execution, include 'detached' in the executionModes array of the agent’s subagentConfig. Set defaultExecutionMode to control which mode the model uses when it does not choose one.
Break large jobs into Records and batches
For a job with hours of genuine model work, model each unit of work as a Record and process the units as batch runs:
- Create a Record for each unit of work, with the unit’s input in the Record fields.
- Run each phase as a batch over those Records. Each Record’s execution gets its own timeout of up to 30 minutes, and the batch runs Records concurrently.
- Persist each phase’s output back onto the Record with an
upsert-recordstep, so the next phase reads its input from the Record rather than from a live execution. - Submit the next phase’s batch when the preceding batch completes. Poll
GET /v1/batch/status/{id}from your own system until the status is terminal:completed,failed, orcancelled. Submit the next batch oncompleted. Onfailedorcancelled, stop the chain and retry or recover the failed Records before continuing.
Schedules can also run phases on a fixed cadence, but a Schedule fires by cron rather than on batch completion, so it cannot wait for the preceding phase. If you chain phases with Schedules, make each phase idempotent: start the phase’s Flow with a check that the Record carries the preceding phase’s output, and skip the Record otherwise, so a run that fires before the preceding phase finishes does no harm and the next firing picks the Record up.
The total wall-clock time of the job is unbounded because each Record execution is its own leg. A 12-hour job becomes a sequence of phases, each of which finishes in minutes per Record.
Size each phase so one Record’s work for that phase fits inside 30 minutes. If a single unit’s phase exceeds that, split the phase into smaller phases or split the unit into smaller Records.
Run multi-session agent tasks from the CLI
For a long agent task that you drive from your own machine, the runtype CLI’s Marathon mode runs a saved Agent across many sessions with checkpoints, resumable state, and cost caps. For more information, see Marathon: long-running agent tasks (CLI).
Next steps
- Running flows in batch: process Records concurrently with per-Record timeouts
- Using record steps (get/list/upsert): persist phase output between runs
- Handling batch failures: retry and recover failed Records in a batch