Skip to main content
Version: Next

Scheduler

This guide explains how to configure and use Platformatic's built-in scheduler. The scheduler allows you to run periodic tasks by making HTTP requests at scheduled intervals using cron expressions. Note that the scheduler is in-memory only, so no information is persisted between restarts.

Overview

The Platformatic scheduler enables you to configure automated HTTP requests that run according to a specified schedule. This feature is useful for:

  • Periodic data synchronization
  • Scheduled maintenance tasks
  • Recurring API calls
  • Implementing workflows that need to run at specific times

Configuration

The scheduler is configured using an array of job definitions in your Platformatic configuration file.

Here's a basic example:

//...
"scheduler": [
{
"name": "my-scheduled-job",
"cron": "*/5 * * * *",
"callbackUrl": "http://localhost:3042/my-endpoint",
"method": "GET"
}
]

//...

Job Configuration Options

Each job in the scheduler can include the following options:

OptionTypeRequiredDescription
nameStringYesA unique identifier for the job
cronStringYesA cron expression defining the schedule
callbackUrlStringYesThe URL to call when the job is triggered
enabledBooleanNo (defaults to true)If false, the job is disabled.
methodStringNo (defaults to 'GET')HTTP method to use (GET, POST, PUT, DELETE)
headersObjectNoHTTP headers to include in the request
bodyString / ObjectNoRequest body (for POST/PUT requests)
maxRetriesNumberNo (defaults to 3)Number of retries attempts

Cron Expression Format

The scheduler uses standard cron expressions with an optional seconds field. Examples:

  • */1 * * * * * - Every second
  • 0 */5 * * * * - Every 5 minutes
  • 0 0 * * * * - Every hour
  • 0 0 12 * * * - Every day at noon
  • 0 0 0 * * 1 - Every Monday at midnight

See crontab.guru for more examples.

Example: call application in the mesh network

It is possible (and useful) to call also applications in the platformatic mesh network. Here's an example configuring a job that sends a POST request every minute to an internal notification application (so exposed as http://notification.plt.local in the mesh network).

//...
"scheduler": [
{
"name": "send-message",
"cron": "0 */1 * * * *",
"callbackUrl": "http://notification.plt.local/message",
"method": "POST",
"headers": {
"content-type": "application/json",
},
"body": {
"message": "Scheduled notification",
"type": "info"
}
}
]
//..

External coordination

Watt exposes its scheduler through the runtime management API. A coordinator can inspect jobs, pause Watt's local trigger, and execute a job on demand:

OperationManagement API
List jobsGET /api/v1/scheduler
Pause a jobPOST /api/v1/scheduler/:name/pause
Resume a jobPOST /api/v1/scheduler/:name/resume
Run a jobPOST /api/v1/scheduler/:name/run

The same operations are available from the Watt CLI:

wattpm scheduler [runtime]
wattpm scheduler:pause [runtime] <name>
wattpm scheduler:resume [runtime] <name>
wattpm scheduler:run [runtime] <name>

See the Watt CLI command reference for the command arguments and output details.

scheduler lists the jobs and their current pause and next-run state. The other commands pause, resume, or execute a job immediately. The runtime argument can be a process ID or runtime name and can be omitted when only one runtime is available.

The runtime API exposes the same list as getSchedulerJobs(), returning SchedulerJob[]. The HTTP management API and control client wrap that list as { jobs: RuntimeSchedulerJob[] }.

Pausing a job stops future local triggers but does not cancel an execution that is already running. The coordinator should pause a job before taking ownership and resume it when returning ownership to Watt.

Scheduler execution is at least once. HTTP retries, coordinator retries, or ownership changes around a cron tick can run a job more than once, so scheduled handlers should be idempotent.

Nuxt scheduled tasks

Nuxt applications can hand their Nitro schedules to Watt by adding the Platformatic scheduler module:

export default defineNuxtConfig({
modules: ['@platformatic/nuxt/scheduler']
})

The module disables Nitro's in-process cron runner and reports the configured task groups to Watt. Watt registers them as application scheduler jobs and invokes the tasks through its internal communication channel. It does not add HTTP control routes to the Nuxt application.

Without an external coordinator, Watt executes these jobs locally. An external coordinator uses the same Watt pause, resume, and run operations as it does for jobs from the runtime configuration.

Nitro scheduled tasks

Nitro applications can use the same integration by adding the Platformatic scheduler module to nitro.config:

import { defineNitroConfig } from 'nitropack/config'

export default defineNitroConfig({
experimental: { tasks: true },
modules: ['@platformatic/nitro/scheduler'],
scheduledTasks: {
'0 0 1 1 *': ['smoke']
}
})

Define tasks in Nitro's tasks directory. The module disables Nitro's in-process cron runner, reports the configured task groups to Watt, and writes a scheduler manifest to the production output. Watt registers the groups as application scheduler jobs and invokes the tasks through its internal communication channel.

Nitro must have experimental.tasks enabled because Nitro scans task files before installing modules. The module also enables this option for Nitro versions that scan modules later in the build lifecycle.

Without an external coordinator, Watt executes Nitro jobs locally. Coordinators can use Watt's pause, resume, and run operations described above. Scheduled execution is at least once, so Nitro task handlers should be idempotent.

Node scheduled tasks

Node applications export scheduledTasks and matching task handlers from their entrypoint's top level. Each cron expression can run one or more named tasks:

export const scheduledTasks = {
'0 */5 * * * *': ['cleanup', 'syncUsers']
}

export const tasks = {
async cleanup ({ scheduledTime, app }) {
// ...
},
async syncUsers ({ scheduledTime }) {
// ...
}
}

Watt registers each schedule with its Runtime scheduler and invokes handlers with the scheduled timestamp. Task groups run concurrently; a failed handler marks the group as failed and lets the Runtime apply its normal retry policy.

See the Node.js scheduled tasks reference for the complete handler contract.