# Set up Arena scheduled jobs

Add a cron schedule to an ArenaJob so Arena runs the same evaluation automatically, such as a nightly regression suite.

## Prerequisites

- Enterprise features enabled in your Omnia install.
- An [ArenaProject](/reference/evaluation/arenaproject/) that holds the scenarios to run.

## Create the schedule

An ArenaJob with a `schedule` is a template. Each firing creates an ArenaRun from a copy of the job's spec.

1. Add a `schedule` section to the ArenaJob. `sourceRef.name` is the ArenaProject:

   ```yaml
   apiVersion: omnia.altairalabs.ai/v1alpha1
   kind: ArenaJob
   metadata:
     name: nightly-regression
     namespace: arena
   spec:
     sourceRef:
       name: regression-suite
     type: evaluation
     workers:
       replicas: 2
     schedule:
       cron: "0 2 * * *"        # 2:00 AM daily
       timezone: "America/New_York"
       concurrencyPolicy: Forbid
   ```

2. Apply it:

   ```bash
   kubectl apply -f nightly-regression.yaml
   ```

To create the schedule from the dashboard instead, open the project, select **Run this project**, and tick **Repeat on a schedule**. Fill in **Cron**, **Timezone** and **If a run is still going**. The button then reads **Create schedule**, and nothing runs until the cron first fires. The dialog defaults the timezone to your browser's, whereas an ArenaJob that names none uses UTC.

`cron` takes five space-separated fields: minute, hour, day of month, month and day of week (0-6, Sunday is 0). `timezone` takes an IANA name such as `UTC` or `Europe/London`. A cron expression or timezone that does not parse stops the job scheduling (see Troubleshooting).

| Schedule | Cron |
|----------|------|
| Every day at 2:00 | `0 2 * * *` |
| Every hour | `0 * * * *` |
| Every 6 hours | `0 */6 * * *` |
| Sundays at 3:00 | `0 3 * * 0` |
| Monday to Friday at 8:00 | `0 8 * * 1-5` |
| 1st of the month at 4:00 | `0 4 1 * *` |

A daily schedule in a timezone with daylight saving fires twice on the fall-back day and not at all on the spring-forward day, as a Kubernetes CronJob does. Make scheduled work safe to repeat.

## Choose what happens on overlap

`concurrencyPolicy` decides what a tick does while a previous run is still going. The default is `Forbid`.

| Value | Dashboard label | Behavior |
|-------|-----------------|----------|
| `Forbid` | Skip the new one | Skips the tick; the job records a `RunSkipped` event |
| `Allow` | Run both | Starts the new run alongside the old one |
| `Replace` | Cancel the old one | Sets `spec.cancelled` on the running runs, then starts the new one |

- Pick `Forbid` when runs compete for the same providers or write results that must not overlap.
- Pick `Allow` when every tick must run and the cluster has capacity for the overlap.
- Pick `Replace` when only the latest result matters. It cancels work in progress.

## Control how long runs are kept

Set the history limits so a nightly job does not accumulate ArenaRuns. The defaults keep the 3 newest successful runs and 1 failed run:

```yaml
spec:
  successfulRunsHistoryLimit: 7
  failedRunsHistoryLimit: 3
```

`ttlSecondsAfterFinished` sets how long Kubernetes keeps each run's finished worker Job and pods (default 3600). It does not delete ArenaRuns. See [ArenaJob](/reference/evaluation/arenajob/#schedule) for every schedule and retention field.

To copy each run's output files to S3, add an `output` section as described in [Configure Arena S3 result storage](/how-to/evaluation/configure-arena-s3-storage/).

## Run the job once now

An ArenaJob with no `schedule` runs once when the controller first sees it. To get an extra run of a scheduled job's configuration, create a second job without a schedule:

```bash
kubectl create -f - <<EOF
apiVersion: omnia.altairalabs.ai/v1alpha1
kind: ArenaJob
metadata:
  generateName: manual-regression-
  namespace: arena
spec:
  sourceRef:
    name: regression-suite
  type: evaluation
  workers:
    replicas: 2
EOF
```

## Suspend and resume

Suspending stops the job starting new runs and keeps the job and its run history. Runs already going are left alone; to stop one, set `spec.cancelled` on the ArenaRun.

```bash
kubectl patch arenajob nightly-regression -n arena --type=merge -p '{"spec":{"suspend":true}}'
```

Resume with `"suspend":false`.

While the job is suspended, `status.nextScheduleTime` is cleared. After you resume, the job fires once on its next due tick and does not replay the ticks it missed.

From the dashboard, open **Runs**. Schedules are listed above the runs, with **Fires**, **State**, **Last**, **Next** and **If one is still running** columns and a **Suspend** or **Resume** button per row. The list appears only when the workspace has a schedule.

Deleting the job deletes its ArenaRuns, because the job owns them.

## Verify

1. Check the scheduling status. `-o wide` adds the next schedule time:

   ```bash
   kubectl get arenajob nightly-regression -n arena -o wide
   ```

   `status.lastScheduleTime` is the last tick that fired and `status.nextScheduleTime` the next one.

2. List the runs the job created:

   ```bash
   kubectl get arenaruns -n arena -l omnia.altairalabs.ai/arena-job=nightly-regression
   ```

3. Read the job's events. A tick that fires records `RunCreated`; a tick skipped by `Forbid` records `RunSkipped`:

   ```bash
   kubectl describe arenajob nightly-regression -n arena
   ```

Phase, progress and results are on each ArenaRun, not on the ArenaJob. See [Monitor Arena jobs](/how-to/evaluation/monitor-arena-jobs/).

## Troubleshooting

### The job never fires

Run `kubectl describe arenajob nightly-regression -n arena`. If the `Ready` condition is `False` with reason `InvalidSchedule`, the cron expression or timezone does not parse. The controller stops until you correct the spec. Also check that `spec.suspend` is not `true`.

### A tick produced no run

With `concurrencyPolicy: Forbid`, a tick that arrives while a run is active is skipped and recorded as a `RunSkipped` event. The skipped tick is not retried when the run finishes.

## Related pages

- [ArenaJob reference](/reference/evaluation/arenajob/#schedule): every schedule field
- [Monitor Arena jobs](/how-to/evaluation/monitor-arena-jobs/): track runs and results
- [Configure Arena S3 result storage](/how-to/evaluation/configure-arena-s3-storage/): copy scheduled runs' output files to a bucket