Skip to main content

mastra.schedules

Added in: @mastra/core@1.50.0

mastra.schedules is the CRUD service for persisted cron schedules. Use it to create, list, update, pause, resume, manually run, and delete schedules for agents or workflows.

For usage patterns and concepts, see Schedules.

Delivery guarantees
Direct link to Delivery guarantees

Scheduled publication is best-effort, not at-least-once delivery. The scheduler atomically claims an occurrence and advances nextFireAt before publishing the agent or workflow start event. An exhausted cron schedule is marked completed in that claim. Completion means there are no remaining occurrences, not that the target started or succeeded.

The scheduler makes up to three publication attempts for the same claimed occurrence, waiting 100 ms and then 200 ms between attempts. A transport can accept an event before returning an error, so retries can publish duplicates with the same run ID.

After all three attempts fail, the scheduler logs the schedule ID, run ID, scheduled fire time, publicationOutcome: 'unknown', and automaticReplay: false. It invokes the configured scheduler.onError hook and attempts to record a trigger with outcome failed. This failure describes the publication attempts. It doesn't prove that the target never started.

Once those attempts are exhausted, the scheduler doesn't replay the occurrence. Recurring schedules remain active and can fire at their next scheduled time. Terminal schedules remain completed with any recorded failure details in trigger history.

After a successful claim, an info-level Claimed schedule occurrence log identifies the schedule ID, run ID, and scheduled fire time. A matching Published schedule occurrence log reports transport acceptance. If neither that success log nor the final failure log follows a claim, publication is unconfirmed. These logs aren't durable state: a crash between the claim commit and logging, or before logs are flushed, can leave no log record.

If a publisher process dies after the claim commits, or confirmation is lost, that occurrence may be skipped without a failed trigger. A replacement scheduler can't distinguish an unpublished event from one accepted before the crash using claim metadata or missing trigger history. It doesn't replay the occurrence or block later recurring fires. A publication acknowledgement also doesn't guarantee target execution, and transport redelivery can produce duplicates.

Before manually rerunning missed work, check target execution and transport records independently. Missing trigger history or a failed publication attempt alone isn't evidence that rerunning is safe.

Usage example
Direct link to Usage example

Create an agent schedule:

src/mastra/schedules.ts
const schedule = await mastra.schedules.create({
agentId: 'pinger',
cron: '0 * * * *',
prompt: 'Give me a status update.',
})

Create a workflow schedule:

src/mastra/schedules.ts
const schedule = await mastra.schedules.create({
workflowId: 'daily-report',
cron: '0 9 * * *',
inputData: { reportType: 'summary' },
})

Schedules require a storage adapter that implements the schedules domain. Supported adapters include @mastra/libsql, @mastra/pg, @mastra/mysql, @mastra/mongodb, @mastra/convex, and @mastra/spanner.

Methods
Direct link to Methods

Create schedules
Direct link to Create schedules

create(input)
Direct link to createinput

Creates an agent or workflow schedule. Pass agentId to create an agent schedule, or workflowId to create a workflow schedule.

const schedule = await mastra.schedules.create({
agentId: 'pinger',
cron: '0 * * * *',
prompt: 'Give me a status update.',
})
Agent schedule input
Direct link to Agent schedule input

id?:

string
Optional stable schedule ID. The value is normalized to agent_<slug>. When omitted, Mastra generates an agent_<uuid> ID.

agentId:

string
ID of the agent to run on each schedule fire.

cron:

string
Cron expression for the schedule. Accepts 5-, 6-, or 7-part cron expressions and Croner nicknames.

prompt:

string
Prompt sent to the agent on each schedule fire.

name?:

string
Free-form label for distinguishing multiple schedules on the same agent or thread.

timezone?:

string
IANA timezone used to resolve cron fire times, for example America/New_York.

threadId?:

string
Thread that receives the scheduled signal. When omitted, each fire runs threadless with agent.generate().

resourceId?:

string
Resource ID for threaded schedules. Required when threadId is set.

signalType?:

AgentSignalType
Signal type for threaded schedule fires. Defaults to notification.

tagName?:

string
XML tag name used to render the scheduled signal. Defaults to schedule.

attributes?:

AgentSignalAttributes
Attributes rendered on the scheduled signal XML tag.

providerOptions?:

Record<string, unknown>
JSON-safe provider options merged into the schedule signal payload on every fire.

ifActive?:

ScheduleIfActive
Behavior when the target thread is actively streaming. Requires threadId.

ifIdle?:

ScheduleIfIdle
Behavior when the target thread is idle. Requires threadId.

metadata?:

Record<string, unknown>
Arbitrary metadata stored with the schedule row.

status?:

'active' | 'paused'
= 'active'
Initial lifecycle status. Defaults to active.
Workflow schedule input
Direct link to Workflow schedule input

id?:

string
Optional stable schedule ID. The value is normalized to schedule_<slug>. When omitted, Mastra generates a schedule_<uuid> ID.

workflowId:

string
ID of the workflow to start on each schedule fire.

cron:

string
Cron expression for the schedule. Accepts 5-, 6-, or 7-part cron expressions and Croner nicknames.

timezone?:

string
IANA timezone used to resolve cron fire times.

inputData?:

unknown
Input data passed to the workflow run.

initialState?:

unknown
Initial workflow state for the scheduled run.

requestContext?:

Record<string, unknown>
Request context passed to the workflow run.

metadata?:

Record<string, unknown>
Arbitrary metadata stored with the schedule row.

status?:

'active' | 'paused'
= 'active'
Initial lifecycle status. Defaults to active.

Read schedules
Direct link to Read schedules

get(id)
Direct link to getid

Gets a schedule by ID. Bare agent schedule IDs are also resolved to the normalized agent_<slug> form.

const schedule = await mastra.schedules.get('pinger')

list(filter?)
Direct link to listfilter

Lists schedules. Without a filter, it returns agent and workflow schedules.

const schedules = await mastra.schedules.list({
agentId: 'pinger',
status: 'active',
})

filter?:

ListSchedulesFilter
Optional filters for the list operation.
ListSchedulesFilter

agentId?:

string
Return only agent schedules for this agent.

workflowId?:

string
Return only workflow schedules for this workflow.

threadId?:

string
Return only agent schedules for this thread.

resourceId?:

string
Return only agent and workflow schedules for this resource.

name?:

string
Return only agent schedules with this label.

status?:

'active' | 'paused' | 'completed'
Return only schedules with this status. The default listing omits completed schedules.

Update schedules
Direct link to Update schedules

update(id, patch)
Direct link to updateid-patch

Updates a schedule. Changing cron or timezone recomputes the next fire time. Updating status from paused to active also recomputes the next fire time. A schedule becomes completed once its cron has no future occurrence. A cadence edit that leaves no future occurrence completes the row even when it was paused. Editing the cadence of a completed schedule reactivates it when the new cadence can still fire, and leaves it completed when it can't.

const updated = await mastra.schedules.update('pinger', {
cron: '*/30 * * * *',
prompt: 'Give me a status update every 30 minutes.',
})

Agent schedule patches can update cron, timezone, prompt, name, signalType, tagName, attributes, providerOptions, ifActive, ifIdle, metadata, and status. threadId and resourceId aren't patchable. Create a new schedule when the thread target needs to change.

Workflow schedule patches can update cron, timezone, inputData, initialState, requestContext, resourceId, metadata, and status. Agent-only patch fields such as prompt, signalType, and ifIdle throw on workflow schedules.

Lifecycle
Direct link to Lifecycle

pause(id)
Direct link to pauseid

Pauses a schedule. Pausing is durable and idempotent.

const paused = await mastra.schedules.pause('pinger')

resume(id)
Direct link to resumeid

Resumes a paused schedule and recomputes the next fire time from the current time. A paused schedule whose cron has no future occurrence is completed instead of resumed.

const active = await mastra.schedules.resume('pinger')

run(id)
Direct link to runid

Fires a schedule once immediately without changing its cron cadence.

const run = await mastra.schedules.run('pinger')

For agent schedules, claimId uses manual_<scheduleId>_<timestamp>. For workflow schedules, claimId uses sched_<scheduleId>_<timestamp> and is reused as the workflow run ID.

delete(id)
Direct link to deleteid

Deletes a schedule. Deleting a missing schedule is a no-op.

await mastra.schedules.delete('pinger')

Schedule behavior
Direct link to Schedule behavior

  • Agent schedule IDs use the agent_ prefix. Workflow schedule IDs created through mastra.schedules.create() use the schedule_ prefix.
  • Threaded agent schedules require resourceId when threadId is set.
  • On agent schedules, signalType, ifActive, ifIdle, and resourceId require threadId. Workflow schedules accept resourceId without a thread.
  • Workflow schedules don't accept agent-only patch fields such as prompt, signalType, or ifIdle.
  • run() publishes a manual fire immediately and doesn't change the stored cron cadence.