Runlane
ReferenceApplication API

Runtime

Create a runtime, trigger work, and manage workers and maintenance.

Import createRunlane and the option types on this page from @runlane/core. A runtime joins your task definitions to a lane. The lane supplies storage and delivery.

Create a runtime

createRunlane(options) returns a RunlaneRuntime. It does not start a worker or a maintenance loop.

OptionType and behavior
laneRequired Lane. Use a lane package that matches your deployment.
queuesRequired, nonempty list of QueueDefinition values. Register every queue used by this runtime.
tasksOptional list of task definitions or a named catalog, such as { sendEmail }. Workers need the tasks they execute.
environmentOptional { name: string }. Defaults to contractDefaults.environment. Processes sharing runs must use the same name.
dispatchOptional { onTrigger: TriggerDispatchMode }. Defaults to contractDefaults.dispatch.onTrigger.
workerIdOptional worker ID. Runlane creates one when omitted.
clockOptional Clock with now(): Date. Defaults to the system clock. Use a controlled clock in tests.
observabilityOptional logging, tracing, observation, and durable export settings. See telemetry.

TriggerDispatchMode.Eager tries to publish a stored delivery request during the trigger call. TriggerDispatchMode.Deferred leaves publishing to maintenance. Both store the run first. Storage-polling workers read due work from storage.

The runtime exposes environment, lane, queues, and the supplied tasks catalog as read-only properties. It also exposes the runs, signals, wait, and idempotency APIs.

Call await runlane.start() before using the runtime. Close worker and service handles before calling await runlane.close() to release lane resources. See add Runlane to your app for complete entry points.

Trigger or run now

CallReturn valueBehavior
trigger(task, payload, options?)Promise<TriggerRunResult>Stores a run and requests delivery. The result has outcome and run. The outcome is created or returned_existing.
runNow(task, payload, options?)Promise<RunRecord>Stores a run and executes one attempt in the calling process. A retry or release needs later execution.

Omit payload only when the task's input schema accepts undefined. trigger() does not return the handler's output. Read a completed run with runlane.runs.get(task, runId) when the task has an output schema.

TriggerRunOptions accepts these optional fields:

FieldType and behavior
queueRegistered QueueDefinition. Overrides the task's queue.
runIdRun ID chosen by the caller. Omit it to let Runlane create one.
idempotencyKeyString key used to reuse a run for the same task and environment.
idempotencyKeyTTLDurationString or IdempotencyKeyTTLMode.Active. Controls how long the key remains owned after the run ends. Requires an idempotency key.
singletonKeyString key that blocks another active run in the same task and environment.
concurrencyKeyString key used to share capacity within a bounded queue. Requires a queue with concurrencyLimit.
actorActor identifying who created the run.
metaJsonObject attached to the creation event.
traceCarrierTraceCarrier used to continue a trace.

Call options override matching task key settings. Without a task or call queue, Runlane uses the registered default queue. At most one registered queue may be the default. If no default exists, the task or call must choose a queue.

See prevent duplicate runs for key ownership, expiration, and repeated requests. Use the error reference to handle rejected API calls.

Execution options

RunNowOptions includes the trigger options above and these fields. The execution methods below also accept them unless noted.

FieldType and behavior
leaseDurationOptional DurationString. How long this worker owns the attempt between renewals. Defaults to contractDefaults.lease.duration.
heartbeatIntervalOptional DurationString. Must be shorter than the lease. The default is half the lease duration, capped at 30 seconds.
maxAttemptDurationOptional DurationString. Overrides the task's limit for each attempt. Omit both settings for no attempt deadline.
signalOptional AbortSignal for cooperative shutdown. Pass the handler's context.signal to calls that support cancellation.
workerIdOptional worker ID for this execution.

A lease prevents two workers from owning the same attempt. It is not a time limit on the handler. maxAttemptDuration sets that limit. A timeout records ErrorCode.TaskTimedOut. The run becomes retrying if its retry policy allows another attempt, or failed otherwise.

Workers and delivery

CallReturn value and options
createDeliveryWorker(options?)Promise<DeliveryWorker>. Starts the lane's delivery worker. Takes execution options, concurrency?: number, and queues?: readonly QueueName[].
executeNext(options?)Promise<RunRecord | undefined>. Claims and executes one due run from storage. Takes execution options and queues?: readonly QueueDefinition[]. Returns undefined when no work is available.
executeDelivery(message, options?)Promise<ExecuteDeliveryResult>. Validates and processes one DeliveryMessage from a transport. Intended for delivery integrations.
drain(options?)Promise<DrainResult>, containing runsExecuted. Available on storage-polling lanes. Takes worker options and maxRuns?: number; stops when idle, cancelled, or the limit is reached.
createDeliveryHandler(options?)A platform handler supplied by a transport lane, such as an SQS Lambda handler. Takes execution options except signal. Its request and response types come from the lane.

Worker concurrency defaults to contractDefaults.worker.concurrency. It limits this worker's parallel attempts. A queue's concurrencyLimit is a separate shared limit enforced through storage.

Worker and drain queues take queue names, such as [emails.name]. executeNext() takes queue definitions, such as [emails]. Omitted queue filters include all registered queues. Supplied worker queue lists must be nonempty and must not repeat names. Counts must be positive integers.

A worker handle has close(): Promise<void> and waitUntilClosed(): Promise<void>. Keep its process alive until shutdown. runlane work uses this worker API, so it supports both storage polling and transport consumption for the configured lane.

Let TypeScript infer the runtime type from createRunlane(). Replacing a concrete lane type with the broad Lane type hides methods such as drain() and the platform handler.

Maintenance

Maintenance creates scheduled runs, wakes due work, resolves token deadlines, and publishes pending delivery requests. It does not run task handlers.

CallReturn value and lifecycle
runMaintenanceOnce(options?)Promise<TickResult>. Runs one bounded pass.
createMaintenanceHandler(options?)(options?: TickOptions) => Promise<TickResult>. Runs one pass when invoked. Start the runtime before calling it. Use it with an external scheduler.
startServices(options?)RunlaneServiceHandle. Starts supervised maintenance loops after runlane.start(). Close the handle on shutdown.

TickOptions accepts optional positive integer limits: cancellationFinalizationLimit, deliveryRequestLimit, outboxClaimLimit, scheduleMaterializationLimit, timeoutFinalizationLimit, waitTokenResumeLimit, and waitTokenTimeoutLimit. Their defaults come from the matching fields in contractDefaults.maintenance.

It also accepts clockSkewTolerance?: DurationString and phases?: readonly MaintenancePhase[]. A supplied phase list must be nonempty. Omit it to run all phases:

Enum memberWork performed
MaintenancePhase.DeliveryRecoveryRequests delivery for due work.
MaintenancePhase.OutboxFlushPublishes stored delivery requests.
MaintenancePhase.RunFinalizationFinalizes due cancellations and timeouts.
MaintenancePhase.ScheduleMaterializationCreates due scheduled runs.
MaintenancePhase.WaitTokenResolutionTimes out tokens and resumes their waiting runs.

TickResult contains cancellationsFinalized, deliveryRequested, materialized, outbox, timeoutsFinalized, waitTokenRunsResumed, and waitTokensTimedOut.

StartServicesOptions accepts a duration for each loop: deliveryRecoveryInterval, outboxFlushInterval, runFinalizationInterval, scheduleMaterializationInterval, and waitTokenResolutionInterval. Each defaults to contractDefaults.maintenance.services.interval.

Other service options are maintenance (tick options without phases), maintenanceLeaseDuration, signal, onServiceError(error, { phase }), and onServicePass(result, { phase }). The service handle has close() and waitUntilClosed(), both returning Promise<void>.

See run maintenance for deployment and recovery guidance.

On this page