---
title: Scheduled Tasks
description: "Run a command on a timer inside your application's own container, such as clearing a cache, sending a digest or a nightly cleanup."
---

A scheduled task runs a command on a timer inside your application's own container. It sees the same code, files and environment variables as your running app, so anything you can run from the app's terminal can run on a schedule.

Typical uses:

- Clearing or warming a cache
- Sending a daily or weekly digest email
- Nightly cleanup, such as deleting expired sessions or old uploads

Scheduled tasks are available for applications. Team owners and admins can create, edit and run them.

## Creating a task

Each task has:

| Field | What it is | Example |
|---|---|---|
| **Name** | A label you'll recognise in the run history | `Nightly cleanup` |
| **Command** | What to run inside your app's container | `npm run cleanup` |
| **Frequency** | When to run it (see below) | `daily` or `0 3 * * *` |
| **Timeout** | How long a run may take before it's stopped, from 10 to 3600 seconds | `300` (the default) |
| **Enabled** | Turn a task off without deleting it | on |

Each service can have a limited number of tasks. If you reach the limit, remove one you no longer need to add another.

## Frequency

Use one of the presets, or a standard 5-field cron expression:

| Frequency | Runs |
|---|---|
| `hourly` | At the start of every hour |
| `daily` | Once a day at midnight |
| `weekly` | Once a week |
| `monthly` | Once a month |
| `0 3 * * *` | Every day at 03:00 |
| `*/15 * * * *` | Every 15 minutes |
| `0 9 * * 1` | Every Monday at 09:00 |

The five fields are minute, hour, day of month, month and day of week.

> **Warning: Every 5 minutes at most**
>
> A task can run at most every 5 minutes. A `*` or `*/1` in the minute field is refused. Use `*/5` or a fixed minute instead.

## Runs and output

Every task keeps its recent runs, each with its status and the command's output. Check the output after a task's first scheduled run to confirm it did what you expected.

To test a task without waiting for the schedule, run it now. That runs the command once, straight away, and the run appears in the history like any other.

> **Tip: Keep the command small**
>
> Put the real work in a script in your repository (for example a `cleanup` script in `package.json` or a management command) and have the task run that. The script is versioned with your code and you can run it locally the same way.

## API

Owners and admins can manage tasks through the API.

```
GET /v1/services/:serviceId/scheduled-tasks
```

```
POST /v1/services/:serviceId/scheduled-tasks
```

```json
{
  "name": "Nightly cleanup",
  "command": "npm run cleanup",
  "frequency": "0 3 * * *",
  "timeout": 300,
  "enabled": true
}
```

`timeout` and `enabled` are optional. `timeout` defaults to 300 seconds.

```
PATCH /v1/services/:serviceId/scheduled-tasks/:taskId
```

Send only the fields you want to change.

```
DELETE /v1/services/:serviceId/scheduled-tasks/:taskId
```

```
POST /v1/services/:serviceId/scheduled-tasks/:taskId/run
```

Runs the task once, now.

```
GET /v1/services/:serviceId/scheduled-tasks/:taskId/runs
```

Recent runs with their status and output.
