mcpField
S
serverpod-scheduling

serverpod-scheduling

github.com/serverpodDevelopment3.3k44 installsUpdated 1d ago
Repository

About serverpod-scheduling

A Serverpod skill for scheduling database-backed calls to run later or at a specified UTC time. It covers generated, type-safe scheduling and configuration for execution across a cluster.

Key features

  1. 01Delayed and scheduled-time calls
  2. 02Database-backed persistence across restarts
  3. 03Cluster-wide single execution claims
  4. 04Generated type-safe API
  5. 05Execution and concurrency settings

Use cases

  1. 01Run work after a delay
  2. 02Schedule work for a UTC time
  3. 03Keep scheduled tasks through restarts

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/serverpod/serverpod --skill serverpod-scheduling

After installing, type/serverpod-schedulingin Claude Code to confirm it loaded.

Details

From the project README

Serverpod Scheduling (Future Calls)

Future calls run at a specified time, are stored in the database, and survive restarts. Each call is claimed for one execution across the cluster. Future calls require database support; execution is started by monolith/maintenance roles, not serverless role.

Defining a future call

class ExampleFutureCall extends FutureCall {
  Future<void> doWork(Session session) async {
    // Work here.
  }

  Future<void> doOtherWork(Session session, MyModel data) async {
    // Work with data.
  }
}

Run serverpod generate for the type-safe API on pod.futureCalls.

Supported parameter types

The same types as for endpoint methods, listed in Serverpod Endpoints.

Scheduling

// Delay
await pod.futureCalls
    .callWithDelay(const Duration(hours: 1))
    .example.doWork();

// At specific time (UTC)
await pod.futureCalls
    .callAtTime(DateTime.utc(2026, 1, 1))
    .example.doOtherWork(myModel);

// With identifier (for cancellation)
await pod.futureCalls
    .callWithDelay(const Duration(hours: 1), identifier: 'my-job-id')
    .example.doWork();

// Recurring task from `Duration` interval with an optional start time
await pod.futureCalls
    .callRecurring()
    .every(const Duration(hours: 1), start: DateTime.now())
    .example.doWork();

// Recurring task from `cron` expression
await pod.futureCalls
    .callRecurring()
    .cron("0 * * * *")
    .example.doWork();

await pod.futureCalls.cancel('my-job-id');  // Cancels all with that identifier

Handle failures inside the call and reschedule if the work must eventually succeed.

Configuration

futureCall:
  enabled: true                   # SERVERPOD_FUTURE_CALL_ENABLED (default true)
  executionEnabled: true          # SERVERPOD_FUTURE_CALL_EXECUTION_ENABLED
  concurrencyLimit: 5             # SERVERPOD_FUTURE_CALL_CONCURRENCY_LIMIT (default 1, <1 maps to unlimited and is not recommended)
  scanInterval: 2000              # SERVERPOD_FUTURE_CALL_SCAN_INTERVAL (ms, default 5000)

futureCallExecutionEnabled: false only stops execution; calls can still be scheduled. futureCall.enabled: false disables future calls entirely: no future call manager is created and serverpod generate omits the pod.futureCalls getter. The value must match across all run-mode config files, or generation fails.

Keep future calls idempotent. A call should tolerate retries or restarts without duplicating irreversible side effects.

Comments

Markdown supported