# Scheduled jobs

> Run a container to completion, once or on a cron schedule. Migrations, backfills, imports, and recurring maintenance, with run history and a Run now button.

A **Job** is one of Ownkube's resource types. Unlike a web app or worker, a job runs a container **to completion and exits**, it isn't a long-running server. Create one from your [**dashboard**](https://app.ownkube.io/dashboard) by choosing **Job** as the resource type, the same flow as a web app.

Jobs run on Ownkube-managed compute and, on the own-cloud path, in your own cluster, same as other deployments.

## One-off or scheduled

### One-off

Runs once, on demand. Good for migrations, backfills, one-time imports, or anything you trigger and walk away from.

### Scheduled

Runs on a cron expression, recurring on its own. Good for nightly cleanups, periodic syncs, or report generation.

## Creating a job

1. **Choose Job as the resource type**

   From [**Create deployment**](https://app.ownkube.io/dashboard), pick **Job** instead of Web or Worker.

2. **Point at an image**

   Same container fields as any other deployment: registry, repository, tag. See [Deployments](/docs/features/deployments).

3. **Set the command**

   The command the container runs. This is what does the work and then exits.

4. **Decide one-off or scheduled**

   Leave the schedule empty to run the job once when you create it (or on demand later). Set a cron expression to make it recurring.

5. **Create**

   Ownkube provisions the job. A scheduled job starts firing on its next scheduled tick; a one-off job runs once immediately.

## What you configure

Every field below lives on the job's **Settings** tab and is editable after creation. Saving rebuilds the job.

- **Schedule**, a cron expression for recurring jobs, plus a start deadline (how long a scheduled run can wait to start before it's skipped) and history limits (how many past runs to keep)
- **Command**, what the container runs
- **Resources**, CPU and memory requests and limits, same as any other deployment
- **Execution controls**:
  - **Restart policy**, what happens when a run's container exits with an error
  - **Retry / backoff**, how many times a failed run retries and the delay between attempts
  - **Timeout (active deadline)**, how long a single run is allowed to keep going before it's killed
  - **Cleanup (TTL after finish)**, how long a finished run's resources stick around before Ownkube cleans them up
  - **Parallelism**, how many pods run at once for a single job run
  - **Completions**, how many successful pod completions a run needs before it's considered done

A cron expression example, run daily at 3am UTC:

```
0 3 * * *
```

## The Runs tab

The job detail page has a **Runs** tab alongside the usual **Overview** and **Settings**:

- **Run history**, a live list of past and in-progress runs with status
- **Run now**, trigger an immediate run outside the schedule
- **Cancel**, stop an in-progress run

Logs and metrics work the same as any other deployment. See [Monitoring](/docs/features/monitoring).

## Limits and constraints

Jobs are a different shape from web apps and workers:

- **No port.** Jobs don't listen for traffic.
- **No replicas.** A job run is a fixed number of pods driven by parallelism and completions, not a replica count you scale.
- **No public URL.** Jobs never get a hostname.
- **No autoscaling.** There's nothing to scale in response to load.

- [Deployments](/docs/features/deployments)
- [Environment variables](/docs/guides/environment-variables)

---

**Don't see a feature you need?** Email [support@ownkube.io](mailto:support@ownkube.io?subject=Feature%20request). Ownkube is shaped by the teams using it and we ship what our users ask for.
