diff --git a/docs/config/config-file.mdx b/docs/config/config-file.mdx index 8d34270433..72755a7609 100644 --- a/docs/config/config-file.mdx +++ b/docs/config/config-file.mdx @@ -350,6 +350,22 @@ export default defineConfig({ See our [maxDuration guide](/runs/max-duration) for more information. +## TTL + +You can set a default time-to-live (TTL) for all task runs in your project. If a run is not dequeued within this time, it will expire and never execute. + +```ts trigger.config.ts +import { defineConfig } from "@trigger.dev/sdk"; + +export default defineConfig({ + project: "", + // Your other config settings... + ttl: "1h", // Also accepts a number of seconds, e.g. 3600 +}); +``` + +You can override this on a per-task basis by setting `ttl` on the task definition, or per-trigger by passing `ttl` in the trigger options. See [Time-to-live (TTL)](/runs#time-to-live-ttl) for more information. + ## Process keep alive Keep the process alive after the task has finished running so the next task doesn't have to wait for the process to start up again. diff --git a/docs/runs.mdx b/docs/runs.mdx index 1c61b3ee93..c04539af95 100644 --- a/docs/runs.mdx +++ b/docs/runs.mdx @@ -153,12 +153,35 @@ When a run is canceled: ### Time-to-live (TTL) -TTL is a time-to-live setting that defines the maximum duration a run can remain in a queued state before being automatically expired. You can set a TTL when triggering a run: +TTL is a time-to-live setting that defines the maximum duration a run can remain in a queued state before being automatically expired. You can set a TTL at three levels, with the following precedence: + +1. **Per-trigger** (highest priority): ```ts await yourTask.trigger({ foo: "bar" }, { ttl: "10m" }); ``` +2. **Task-level default**: + +```ts +export const myTask = task({ + id: "my-task", + ttl: "10m", + run: async (payload) => { + //... + }, +}); +``` + +3. **Global config default** (lowest priority): + +```ts trigger.config.ts +export default defineConfig({ + project: "", + ttl: "1h", +}); +``` + If the run hasn't started within the specified TTL, it will automatically expire, returning the status `Expired`. This is useful for time-sensitive tasks where immediate execution is important. For example, when you queue many runs simultaneously and exceed your concurrency limits, some runs might be delayed - using TTL ensures they only execute if they can start within your specified timeframe. Dev runs automatically have a 10-minute TTL. On Trigger.dev Cloud, staging and production runs have a maximum TTL of 14 days applied automatically (runs without an explicit TTL get 14 days; longer TTLs are clamped). See [Limits — Maximum run TTL](/limits#maximum-run-ttl) for details. diff --git a/docs/tasks/overview.mdx b/docs/tasks/overview.mdx index b2bca9bc1e..06cedc8c92 100644 --- a/docs/tasks/overview.mdx +++ b/docs/tasks/overview.mdx @@ -136,6 +136,22 @@ export const longTask = task({ See our [maxDuration guide](/runs/max-duration) for more information. +### `ttl` option + +You can set a default time-to-live (TTL) on a task. If a run is not dequeued within this time, it will expire and never execute. This is useful for time-sensitive tasks where stale runs should be discarded. + +```ts /trigger/time-sensitive-task.ts +export const timeSensitiveTask = task({ + id: "time-sensitive-task", + ttl: "10m", // Also accepts a number of seconds, e.g. 600 + run: async (payload: any, { ctx }) => { + //... + }, +}); +``` + +You can override this per-trigger by passing `ttl` in the trigger options, or set a project-wide default in your [trigger.config.ts](/config/config-file#ttl). See [Time-to-live (TTL)](/runs#time-to-live-ttl) for more information. + ## Global lifecycle hooks When specifying global lifecycle hooks, we recommend using the `init.ts` file. diff --git a/docs/tasks/scheduled.mdx b/docs/tasks/scheduled.mdx index 84985708f6..e3edeee85e 100644 --- a/docs/tasks/scheduled.mdx +++ b/docs/tasks/scheduled.mdx @@ -67,6 +67,18 @@ You can see from the comments that the payload has several useful properties: Like all tasks they don't have timeouts, they should be placed inside a [/trigger folder](/config/config-file), and you [can configure them](/tasks/overview#defining-a-task). +You can set a [TTL](/runs#time-to-live-ttl) on a scheduled task to automatically expire runs that aren't dequeued in time. This is useful when a schedule fires while the previous run is still executing - rather than queueing up stale runs, they'll expire: + +```ts +export const frequentTask = schedules.task({ + id: "frequent-task", + ttl: "5m", + run: async (payload) => { + //... + }, +}); +``` + ## How to attach a schedule Now that we've defined a scheduled task, we need to define when it will actually run. To do this we need to attach one or more schedules.