# Version lifetime and cleanup

How long a saved version lives, which versions the platform always keeps, what happens to the sources of a deleted server, and how snapshots appear in object storage.

Storage overview and the endpoint reference — [Source code storage](/docs/source-storage).

## Version lifetime (retention policy)

After saving, a version goes through automatic cleanup on a Grandfather-Father-Son schedule:

1. **The last 5 versions** are always kept, regardless of tags.
2. **Daily retention for 14 days** — one version for each calendar day (UTC).
3. **Weekly retention for 4 weeks** — one version every 7 days.
4. **Versions tagged `published` or `manual`** — kept indefinitely, never deleted automatically.

For on-demand cleanup — `POST /v1/apps/:id/sources/cleanup`. Versions with the `published` and `manual` tags are excluded from it as well.

Automatic cleanup runs once a day on a schedule, not at the moment a new version is saved or a server is deleted. A version that falls under the rules above stays visible until the next daily pass.

### Versions of a deleted server

Sources outlive the server: after `DELETE /v1/infra/servers/:id` the versions stay in place and remain available for listing and download.

What happens to the objects of a deleted server:

- **Versions are kept** — deleting the server does not touch them. Automatic cleanup keeps applying the usual retention policy described above.
- **The pointer to the latest version is dropped by the daily cleanup** — the `source/current.<ext>` object stays visible in storage until the next pass. For what that object is, see the "Snapshots in object storage" section below.

If you no longer need the versions of a deleted server, remove them manually. **This action is irreversible:** a version cannot be restored through the API, and a new one can no longer be saved on a deleted server — `POST …/sources` returns `404`. Download whatever you need before the cleanup.

1. Find the server — `GET /v1/infra/servers?includeDeleted=true`. Without this parameter, deleted servers are not included in the output.
2. Drop the retention tags from the versions you also want removed — `POST /v1/infra/servers/:id/sources/:versionId/tag` with the body `{"tag": "manual", "action": "remove"}`. This operation removes one tag and does not affect the version's other labels.
3. Clear the history — `POST /v1/infra/servers/:id/sources/cleanup` with the body `{"keepLatest": 0}`. The endpoint works on a deleted server too. Versions that still carry a `manual` or `published` tag are left untouched.

Deleted versions stop counting toward your storage usage right away, and the bytes themselves are erased after 30 days — see [Storage](/docs/storage).

## Snapshots in object storage

Source-code snapshots live in the same object storage as the rest of the application's files and are listed by `GET /v1/storage/objects` under the `source/` prefix. That prefix holds two kinds of objects:

| Key | What it is |
|------|---------|
| `source/versions/v<N>-…` | A saved version. It corresponds to the `v<N>` entry in the version list. |
| `source/current.<ext>` | A pointer to the latest saved version. The extension matches the archive format of the last save. |

For applications that saved snapshots through `POST /v1/apps/:id/sources`, the same prefix also holds `source/manifest.json` — the version list in human-readable form — and `source/README.md` describing the contents.

The logical key `source/current.tar.gz` is not unique: every owner has its own pointer, and physically the objects live in separate namespaces. Several rows carrying the same key in a `GET /v1/storage/objects` response mean different owners — servers or applications — rather than one object being overwritten. The `id` field tells them apart.

Snapshots are managed through the source-code operations — deleting a version and bulk cleanup: they address a version by its owner. The `DELETE /v1/storage/objects/:key` request is not suitable for snapshots: it looks up the row by logical key across all the objects available to the calling key, and the key `source/current.tar.gz` is the same for every owner — an arbitrary one will be deleted.

## See also

- [Source code storage](/docs/source-storage)
- [Deleting versions](/docs/source-storage/delete)
- [Version tags and notes](/docs/source-storage/metadata)
- [Storage](/docs/storage)
- [Delete a server](/docs/infra/servers/delete)
