---
title: "Run"
description: "One execution of a backup. It either produces an artifact or explains why not."
url: "https://saved.sh/docs/concepts/runs"
---

A **run** is one execution attempt of a backup. It has phases, each with steps, and it ends
either with an [artifact](/docs/concepts/artifacts) or with a reason there is none.

## Where runs come from [#where-runs-come-from]

| Origin                          | Created by                           |
| ------------------------------- | ------------------------------------ |
| The schedule firing             | The orchestration layer, not our API |
| `sctl backup trigger`           | You, outside the schedule            |
| Submitting to a `manual` backup | You, by uploading                    |

A triggered run is ordinary in every respect: same pipeline, same artifact, same retention,
same billing. It does not shift the schedule.

<Callout>
  Scheduled fires **skip** when a run is already in flight. Manual triggers **do not**, because
  "run it now" is usually said by someone who means it regardless.
</Callout>

## Phases and steps [#phases-and-steps]

A run has up to two phases.

| Phase         | Runs on              | Does                                                                    |
| ------------- | -------------------- | ----------------------------------------------------------------------- |
| `produce`     | Your worker, or ours | Takes the dump. For local backups, also encrypts, checksums and uploads |
| `post-backup` | Ours, always         | Inspects, compresses, encrypts, delivers, finalizes                     |

Every kind passes through `post-backup`, including manual uploads. It is where the artifact
record is written, and it is written last: a run that stored nothing anywhere fails **before**
finalize, so no artifact exists for a file that does not.

Each step reports its own status, duration and **attempt count**. That last field is what
separates a transient blip from a misconfiguration:

* Failed on attempt 1, succeeded on attempt 2: not a failure.
* Failed on every attempt with the same message: fix the configuration, not the retry policy.

## Statuses [#statuses]

| Status                   | Artifact                   |
| ------------------------ | -------------------------- |
| `Running`                | Not yet                    |
| `Completed`              | Yes                        |
| `Failed`                 | **Usually** not. See below |
| `TimedOut`               | No                         |
| `Terminated`, `Canceled` | No                         |

### The case worth knowing [#the-case-worth-knowing]

A run that stored **some** copies but not all is **failed, with the artifact written**. The
artifact records exactly which copies exist.

That is deliberate. A destination you selected did not get your data, so calling it a success
would be a claim we cannot back, but the copies that did land are real and hiding them would
be worse.

## Run IDs [#run-ids]

| Origin              | Shape                                    |
| ------------------- | ---------------------------------------- |
| Schedule or trigger | `scheduled-<backup-id>-<unix-timestamp>` |
| Manual submission   | `manual-<uuidv7>`                        |

**The ID is stable across retries.** A run that retried is the same run, and its artifact is
filed under the ID you saw. Manual IDs are time-ordered, so they sort chronologically on their
own.

## Failed versus missing [#failed-versus-missing]

Different problems, different evidence.

|                 | Failed                     | Missing                                          |
| --------------- | -------------------------- | ------------------------------------------------ |
| A record exists | Yes, with an error         | No                                               |
| Look at         | The step list              | The schedule, the state, the worker assignment   |
| Usually         | The source or the pipeline | Paused, still draft, or a worker that is offline |

A **local** backup whose worker is offline produces neither. Its runs queue on that worker's
own queue and execute when it returns, late rather than lost. They are never redistributed,
because no other machine has the credentials.

## History is 30 days [#history-is-30-days]

Run history is read live from the orchestration layer rather than mirrored into a database.
That is what makes step-level detail cheap to keep, and it is what bounds how long it lasts.

<Callout type="warn">
  **Artifacts outlive their runs.** An artifact under a 90-day retention exists long after the
  run that produced it stopped being listed. An empty run list means "no history", not "nothing
  ever ran".
</Callout>

If you need run outcomes kept longer, send them somewhere you control as they happen.

## Next [#next]

<Cards>
  <Card href="/docs/concepts/artifacts" title="Artifact" description="What a successful run leaves behind." />

  <Card href="/docs/backups/runs" title="Runs in depth" description="Reading a failure properly." />

  <Card href="/docs/cli/runs" title="sctl run" description="Listing and inspecting." />
</Cards>
