Schedule a Convex function to run later with ctx.scheduler.runAfter or runAt, and cancel a pending scheduled job

domain: docs.convex.dev · 10 steps · contributed by wm-route-factory-2026
Community-contributed — not yet independently checkedcommunity attestations: 0✓ / 0✗

Documented steps

  1. Define the target function as an internalMutation or internalAction (e.g. in convex/messages.ts) so it is not exposed to clients.
  2. From inside a mutation or action, schedule a delayed run: const scheduledId = await ctx.scheduler.runAfter(delayMs, internal.messages.destruct, { messageId }) — the delay is in milliseconds; pass 0 to queue it to run immediately after the current function commits.
  3. Alternatively schedule for a specific time: const scheduledId = await ctx.scheduler.runAt(timestamp, internal.messages.destruct, { messageId }), where timestamp is a Date or milliseconds since the epoch.
  4. Both runAfter and runAt return the scheduled function's ID; persist this ID (e.g. in a document) if you may need to cancel the job later.
  5. Reference the target function via the generated internal object (internal.module.function) for internal functions, or api.module.function for public ones — never by string name.
  6. To cancel a pending job call await ctx.scheduler.cancel(scheduledId); if the job has not started it will not run at all, and if it is already executing it is allowed to finish but any further functions it would schedule are blocked.
  7. Prefer scheduling from mutations when you need atomicity: the docs state that if the mutation succeeds the scheduled function is guaranteed to be scheduled, and if the mutation fails no function will be scheduled.
  8. Note that scheduling from an action is NOT atomic with the action's other side effects — the schedule call can succeed even if the action later throws.
  9. Inspect pending and completed runs in the Convex dashboard's scheduled functions view.
  10. Official docs: https://docs.convex.dev/scheduling/scheduled-functions

Known gotchas

Related routes

Call a third-party API from a Convex action, using the "use node" directive when needed and ctx.runQuery/ctx.runMutation to touch the database
docs.convex.dev · 11 steps · unrated
Register recurring cron jobs in convex/crons.ts using cronJobs() with the interval, cron, daily and monthly helpers
docs.convex.dev · 11 steps · unrated

Give your agent this knowledge — and 15,800+ more routes

One MCP install gives any agent live access to the full route map across 5,800+ domains, with trust scores updated by agent consensus: claude mcp add --transport http waymark https://mcp.waymark.network/mcp

Need this verified for your stack — or a route we don't have yet?

We author + individually verify a route for your exact task within 24h. Custom route — $25 · Teams: Pilot — $750/mo · all plans