Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion docs/06-concepts/14-scheduling/01-setup.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
---
description: Schedule future work in Serverpod using future calls — invoke methods after a delay, at a specific time, or on a recurring interval, with persistence across restarts.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: em dash slipped in here. A colon keeps the same structure.

Suggested change
description: Schedule future work in Serverpod using future calls invoke methods after a delay, at a specific time, or on a recurring interval, with persistence across restarts.
description: Schedule future work in Serverpod using future calls: invoke methods after a delay, at a specific time, or on a recurring interval, with persistence across restarts.

---

# Setup

Serverpod supports scheduling future work with the `future call` feature. Future calls are calls that will be invoked at a later time. An example is if you want to send a drip-email campaign after a user signs up. You can schedule a future call for a day, a week, a month, or a [recurring interval](recurring-task). The calls are stored in the database, so they will persist even if the server is restarted.
Expand Down Expand Up @@ -40,7 +44,6 @@ The future calls you create are registered by `Serverpod` after the server start

```dart
import 'package:serverpod/serverpod.dart';
import 'package:serverpod_auth_idp_server/core.dart';

import 'src/generated/protocol.dart';
import 'src/generated/endpoints.dart';
Expand Down
33 changes: 18 additions & 15 deletions docs/06-concepts/14-scheduling/02-recurring-task.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
---
description: Implement cron-like recurring tasks in Serverpod by scheduling a future call from within itself to re-run at a fixed interval.
---

# Recurring Task

The recommended way to achieve cron-like scheduling is by scheduling a future call inside another.
Expand Down Expand Up @@ -49,23 +53,22 @@ class ExampleFutureCall extends FutureCall {
}
```

Now when you schedule the `doWork` future call, it will continously invoke `_doWork` at an interval of 20 minutes.
Now when you schedule the `doWork` future call, it will continuously invoke `_doWork` at an interval of 20 minutes.

```dart
import 'package:serverpod/serverpod.dart';
import 'package:serverpod_auth_idp_server/core.dart';
import 'src/generated/protocol.dart';
import 'src/generated/endpoints.dart';
void run(List<String> args) async {
final pod = Serverpod(
args,
Protocol(),
Endpoints(),
);
await pod.start();
import 'package:serverpod/serverpod.dart';
import 'src/generated/protocol.dart';
import 'src/generated/endpoints.dart';
void run(List<String> args) async {
final pod = Serverpod(
args,
Protocol(),
Endpoints(),
);
await pod.start();
await pod.futureCalls.callWithDelay(Duration(minutes: 20)).example.doWork(2);
}
```
6 changes: 5 additions & 1 deletion docs/06-concepts/14-scheduling/03-inheritance.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
---
description: Extend or override FutureCall classes from other Serverpod modules, including support for abstract base classes that expose their methods through subclasses.
---

# Inheritance

Inheritance gives you the possibility to modify the behavior of `FutureCall` classes defined in other Serverpod modules. If the parent `FutureCall` class was marked as `abstract`, no code is generated for it.
Expand Down Expand Up @@ -86,6 +90,6 @@ class ExcitedGreeter extends Greeter {
}
```

Since `Greeter` is `abstract`, it will not be exposed on the server. The `ExcitedGreeter` will expose a single `hello` method, and its implementation will augment the superclass's one by adding `!!!` to the output.
Since `Greeter` is `abstract`, it will not be exposed on the server. The `ExcitedGreeter` will expose a single `hello` method, overriding the superclass implementation by adding `!!!` to the output.

This way, you can modify the behavior of future call methods while still sharing the implementation through calls to `super`. Be aware that the method signature has to be compatible with the base class per Dart's rules, meaning you can add optional parameters, but can not add required parameters or change the return type.
23 changes: 9 additions & 14 deletions docs/06-concepts/14-scheduling/04-configuration.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
---
description: Configure future call execution, concurrency limits, scan interval, and broken call handling in Serverpod using YAML or environment variables.
---

# Configuration

Future calls can be configured using options defined in the configuration files or environment variables. For a detailed list of configuration options, refer to the [Configuration](../configuration) page.

Below is an example of how you can configure future calls in a YAML file:

```yaml
futureCallExecutionEnabled: true

Expand All @@ -16,8 +18,6 @@ futureCall:

This option allows you to enable or disable the execution of future calls. By default, it is set to `true`. You might want to disable future call execution in environments where you don't want background tasks to run, such as during testing or in a staging environment where you want to focus on API behavior without triggering scheduled tasks.

Example configuration:

```yaml
futureCallExecutionEnabled: false
```
Expand All @@ -28,8 +28,6 @@ This option sets the maximum number of future calls that can run concurrently. B

Setting this value to a negative number or `null` removes the limitation, allowing an unlimited number of concurrent future calls. However, this should be used with caution as it can lead to resource exhaustion.

Example configuration:

```yaml
futureCall:
concurrencyLimit: 5 # Adjust this value based on your server's capacity
Expand All @@ -39,8 +37,6 @@ futureCall:

This option determines how often the system scans for future calls to execute, in milliseconds. The default value is `5000` (5 seconds). Adjusting this interval can help balance responsiveness and resource usage. For example, reducing the interval can make future calls execute closer to their scheduled time, while increasing it can reduce database load in environments with limited resources.

Example configuration:

```yaml
futureCall:
scanInterval: 2000 # Adjust this value based on your server's responsiveness needs
Expand All @@ -62,10 +58,9 @@ By default, the server will perform a check for broken future calls on startup i

This check can be controlled using the `checkBrokenCalls` configuration option. If it is set to `true`, the server will perform a check for broken future calls on startup regardless of the number of calls. If it is set to `false`, the server will not perform a check for broken future calls on startup.

Example configuration:

```yaml
checkBrokenCalls: false
futureCall:
checkBrokenCalls: false
```

:::tip
Expand All @@ -74,6 +69,7 @@ The future calls check can be used with the maintenance role to programmatically
```bash
$ dart run bin/main.dart --role maintenance
```

:::

### Delete broken calls
Expand All @@ -82,8 +78,7 @@ When detecting broken future calls, the server will log a warning, but will not

This configuration is only valid if the check is executed (either automatically or through explicitly enabling `checkBrokenCalls`).

Example configuration:

```yaml
deleteBrokenCalls: false
futureCall:
deleteBrokenCalls: false
```
14 changes: 9 additions & 5 deletions docs/06-concepts/14-scheduling/05-legacy.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
---
description: The legacy string-based API for registering and scheduling future calls, prefer the type-safe API for new code.

@developerjamiu developerjamiu Jun 18, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: the comma joins two clauses where a period would read cleaner.

Suggested change
description: The legacy string-based API for registering and scheduling future calls, prefer the type-safe API for new code.
description: The legacy string-based API for registering and scheduling future calls. Prefer the type-safe API for new code.

---

# Legacy

:::warning
This approach is error prone since it involves manually registering and scheduling future calls using string identifiers. The recommended way to interact with the future calls feature is through the [type-safe API](setup).
:::

Creating a future call is simple, extend the `FutureCall` class and override the `invoke` method. The method takes two params the first being the [`Session`](../sessions) object and the second being an optional SerializableModel ([See models](../models)).
To create a future call, extend the `FutureCall` class and override the `invoke` method. The method takes two params: the first is a [`Session`](../sessions) object and the second is an optional serializable model ([See models](../models)).

```dart
import 'package:serverpod/serverpod.dart';
Expand All @@ -17,7 +21,7 @@ class ExampleFutureCall extends FutureCall<MyModelEntity> {
}
```

To let your Server get access to the future call you have to register it in the main run method in your `server.dart` file. You register the future call by calling `registerFutureCall` on the Serverpod object and giving it an instance of the future call together with a string that gives the future call a name. The name has to be globally unique and is used to later invoke the future call.
Register the future call in the `run` function in your `server.dart` file by calling `registerFutureCall` with an instance of the class and a globally unique name string. The name is used to invoke the future call later.

```dart
void run(List<String> args) async {
Expand All @@ -35,7 +39,7 @@ void run(List<String> args) async {
}
```

You are now able to register a future call to be invoked in the future by calling either `futureCallWithDelay` or `futureCallAtTime` depending on your needs.
With the future call registered, you can schedule it using either `futureCallWithDelay` or `futureCallAtTime` depending on your needs.

Invoke the future call 1 hour from now by calling `futureCallWithDelay`.

Expand All @@ -53,12 +57,12 @@ Invoke the future call at a specific time and/or date in the future by calling `
await session.serverpod.futureCallAtTime(
'exampleFutureCall',
data,
DateTime(2025, 1, 1),
DateTime(2030, 1, 1),
);
```

:::note
`data` is an object created from a class defined in one of your yaml files and has to be the same as the one you expect to receive in the future call. in the `model` folder, `data` may also be null if you don't need it.
`data` is an object created from a class defined in one of your yaml model files and must match the type expected by the future call. `data` may also be `null` if you don't need it.
:::

When registering a future call, it is also possible to give it an `identifier` so that it can be referenced later. The same identifier can be applied to multiple future calls.
Expand Down
Loading