Skip to main content
A task is an on-demand, run-to-completion workload defined alongside your applications and services in .upsun/config.yaml. When triggered, a task container is injected into your environment’s cluster, runs a single command, and is removed when the command exits.

When to use a task

A task is the right choice when you need:
  • A background AI agent session — for example, an agent that reads your codebase, calls tools such as shell commands or database queries, and writes the results back to your project.
  • A one-time job that needs service access: database maintenance, a data export, a report.
  • A batch job triggered from your application rather than on a schedule.
For a working example, see the Upsun performance agent, which runs as a task to analyze observability data and generate a report. A task is not the right choice for:
  • A long-running daemon: use a worker.
  • A scheduled job: use a cron.
  • Serving HTTP traffic: tasks are not routable and cannot be used as an upstream in routes:.

How tasks compare to other workloads

Define a task

Tasks are declared at the top level of .upsun/config.yaml, alongside applications: and services:.

Required fields

Common optional fields

Fields that don’t apply

web, workers, and crons have no meaning for tasks. Tasks have no HTTP router, are not long-running, and are not scheduled.

Relationships

A task can declare relationships to applications and services in the same environment: Inside the task container, these relationships appear in PLATFORM_RELATIONSHIPS exactly as they do for applications. The task can read from the database, write to the cache, and POST results back to the app over HTTP. Relationship direction is one-way. Applications and other tasks cannot declare a relationship to a task, because a task exists in the cluster only while a task is running. If you need the app to receive results from a task, the task should push them to the app, for example by using the app: “myapp:http” relationship.

Trigger a task

You can trigger a task from the Console, the Upsun CLI, or through the Upsun API.

From the Console

  1. Open your project or environment overview page.
  2. Find the Tasks card, below Apps & Services.
  3. Hover over the task you want to run to open its detail popover.
  4. Click Run task, optionally provide runtime variables as JSON, and confirm.
The task’s status changes to Running, then back to Idle when it completes.

From the CLI

Run a task using upsun task:run:
If you omit the task name, you’re prompted to choose one interactively. This fails in non-interactive mode (for example, in a CI pipeline), so always pass the task name explicitly there. To pass run-time variables, use --variable in the format <type>:<name>=<value> (repeatable):
By default, the command returns as soon as the task starts. Add --wait to block until it completes:
To see the tasks defined on an environment, run upsun task:list (alias: upsun tasks):
This lists each task’s name, type, command, and timeout. See the Upsun CLI reference for the full list of commands and options.

From the API

To trigger a task through the API, see the task run endpoint reference:
To pass run-time variables to the task, include a variables object in the request body:
$TOKEN is a short-lived access token obtained from your API token. See Authentication for the exchange process and API tokens for the steps to create one. Each invocation creates an activity (the same mechanism used for deploys, backups, and crons) that gives you:
  • A unique activity ID.
  • Live status (pending, in_progress, complete, cancelled).
  • Streamed logs through the existing activity logs endpoint.
  • Cancellation through the /cancel endpoint on the activity.

Trigger from application code

Declare which tasks the app is allowed to trigger using workload authorizations (the authorizations key), then request a short-lived token at runtime — no long-lived credentials required. Steps 1–3 break down each part individually. For a complete implementation combining token retrieval, caching, and triggering, see Sample implementation.

1. Declare the authorization

2. Request a token and trigger the task

3. Cache the token

Token caching is highly recommended if your application triggers tasks repeatedly. Without token caching, every trigger makes a round-trip to the auth proxy. Request a new token only when the current one is about to expire. By default, tokens expire after 60 seconds. The x-token-ttl header extends the lifetime up to 900 seconds (15 minutes) — set it to match your expected time between task triggers. For example, if your app triggers a task every 5 minutes (300 seconds), set x-token-ttl to slightly more than the trigger interval to account for network delays.

Sample implementation

The following examples combine steps 1–3 into a single helper that handles authorization declaration, token retrieval, caching, and task triggering.

Resources, variables, and access

Tasks follow the same model as applications:
  • Resources (CPU, memory): configured by using upsun resources:set against the task name, or in the Console on the Configure resources page.
  • Billing: Per-second for the duration of each run. CPU and memory cost the same as an application; see the Upsun pricing page for rates. Usage is accounted for within the application’s resources; there is no separate usage group for tasks on the billing page.
  • Variables and secrets: configured with upsun variable:create --level environment or by using the API. Sensitive variables are injected as environment variables at run time.
  • Access: standard project roles apply. Project admins and contributors can change task definitions, trigger tasks, and view runs.

Security

Tasks run in the same Linux Containers (LXC) as applications, with the same namespace isolation, capability dropping (removing unnecessary Linux process privileges), seccomp profile, cgroup limits, and network isolation. Cross-project isolation and relationship-based access control apply unchanged. For details, see the Project isolation topic. For tasks that run untrusted code (for example, an LLM-driven agent), consider pairing with bubblewrap inside the task container to restrict filesystem access, environment variables, and syscalls visible to the agent process.

Known limitations

  • Cancelled on deploy. A running task receives SIGTERM before any deploy on the same environment, followed by SIGKILL after a grace period of a few seconds. Catch SIGTERM, persist state to a service, and exit cleanly. The caller is responsible for retrying.
  • Concurrency cap. Multiple task runs can execute in parallel up to a default limit of 3. Further triggers queue behind running ones. During a trial, this limit is lower.
  • No task-to-task relationships. Nothing can declare a relationship to a task. An app and a task can share a relationship to the same service or a network file mount.
  • Fresh filesystem every run. instance and tmp mounts are reset between runs. Use a storage or service mount for files that must survive across runs.
  • Requires at least one application. An Upsun project configuration requires at least one application container to run code, handle routing, and connect to managed services.
Last modified on August 17, 2026