Tasks
Opt-in to the experimental feature
In order to use the tasks API you need to enable experimental feature flag.
import { defineNitroConfig } from "nitro/config";
export default defineNitroConfig({
experimental: {
tasks: true
}
})
Define tasks
Tasks can be defined in tasks/[name].ts files.
Nested directories are supported. The task name will be joined with :. (Example: tasks/db/migrate.tstask name will be db:migrate)
Example:
export default defineTask({
meta: {
name: "db:migrate",
description: "Run database migrations",
},
run({ payload, context }) {
console.log("Running DB migration task...");
return { result: "Success" };
},
});
Scheduled tasks
You can define scheduled tasks using Nitro configuration to automatically run after each period of time.
import { defineNitroConfig } from "nitro/config";
export default defineNitroConfig({
scheduledTasks: {
// Run `cms:update` task every minute
'* * * * *': ['cms:update']
}
})
waitUntil
When running background tasks, you might want to make sure the server or worker waits until the task is done.
An optional context.waitUntil function might be available depending on the runtime.
export default defineTask({
run({ context }) {
const promise = fetch(...)
context.waitUntil?.(promise);
await promise;
return { result: "Success" };
},
});
Platform support
dev,node-server,bunanddeno-serverpresets are supported with croner engine.cloudflare_modulepreset has native integration with Cron Triggers. Make sure to configure wrangler to use the same patterns you define inscheduledTasksto be matched.vercelpreset has native integration with Vercel Cron Jobs. Nitro automatically generates the cron job configuration at build time — no manualvercel.jsonsetup required.- More presets (with native primitives support) are planned to be supported!
Programmatically run tasks
To manually run tasks, you can use runTask(name, { payload? }) utility.
Example:
export default eventHandler(async (event) => {
// IMPORTANT: Authenticate user and validate payload!
const payload = { ...getQuery(event) };
const { result } = await runTask("db:migrate", { payload });
return { result };
});
Run tasks with dev server
Nitro's built-in dev server exposes tasks to be easily executed without programmatic usage.
Using API routes
/_nitro/tasks
This endpoint returns a list of available task names and their meta.
// [GET] /_nitro/tasks
{
"tasks": {
"db:migrate": {
"description": "Run database migrations"
},
"cms:update": {
"description": "Update CMS content"
}
},
"scheduledTasks": [
{
"cron": "* * * * *",
"tasks": [
"cms:update"
]
}
]
}
/_nitro/tasks/:name
This endpoint executes a task. You can provide a payload using both query parameters and body JSON payload. The payload sent in the JSON body payload must be under the "payload" property.
export default defineTask({
meta: {
name: "echo:payload",
description: "Returns the provided payload",
},
run({ payload, context }) {
console.log("Running echo task...");
return { result: payload };
},
});
// [GET] /_nitro/tasks/echo:payload?field=value&array=1&array=2
{
"field": "value",
"array": ["1", "2"]
}
/**
* [POST] /_nitro/tasks/echo:payload?field=value
* body: {
* "payload": {
* "answer": 42,
* "nested": {
* "value": true
* }
* }
* }
*/
{
"field": "value",
"answer": 42,
"nested": {
"value": true
}
}
Using CLI
List tasks
nitro task list
Run a task
nitro task run db:migrate --payload "{}"
Notes
Concurrency
Each task can have one running instance. Calling a task of same name multiple times in parallel, results in calling it once and all callers will get the same return value.