# Persistent volumes

A persistent volume is a durable disk attached to a web service. Everything the service writes under the volume's mount path survives restarts, redeploys, and detaches.

Databases never use these volumes — a [Postgres](/docs/databases/postgres) or Redis database's disk is included automatically, sized from its memory.

A service with a volume runs in volume mode, one of the web [service modes](/docs/services/service-modes): it is pinned to one [location](/docs/services/locations) with exactly one replica, and a volume never combines with serverless or cron mode — the console blocks those toggles while a volume is attached, so detach first to switch. Each volume gets a friendly two-word name of its own, because the disk's identity is independent of whichever service it is attached to.

## Attach a volume

1. 
2. 
3. 
4. 
5.

Attaching is a [staged change](/docs/projects/staged-changes): the disk is created and attached when you deploy, not before. A new volume starts at Koo's base size — grow it any time with an expand (below); through the [API](/api/services), the service's `volume` field also accepts an initial `sizeGb`.

Re-attaching an existing detached volume keeps its data and its location. The disk never moves: the service must run in the disk's location to see its data. Picking a disk that lives in a different location mounts a new, empty disk instead — the console warns you when you pick it, and the deploy asks you to acknowledge starting empty before it goes through (`confirmDataLoss` on the API).

## Detach a volume

1. 
2.

Detaching never deletes data. The disk survives as a detached volume — still listed in the environment, keeping its data and location — and can be re-attached later, to the same service or a different one.

Deleting the service works the same way: its volume is detached and kept, never destroyed.

## Day-2 operations

A volume's drawer has **Overview** and **Snapshots** tabs. Open it by clicking the volume on the environment canvas (a detached volume shows as its own node), or from the volume card in the service's **Settings**. The environment's **Volumes** page — open **Volumes** from the rail on the left of the canvas — reaches the same operations through **Manage**.

> **Note:**
>
> Unlike spec edits, volume operations are not staged — each one runs against the disk the moment you confirm it, with no deploy step. They require the editor role or higher; see [teams and roles](/docs/collaboration/teams-and-roles). The endpoints are in the [Volumes API](/api/volumes).

### Expand

On the **Overview** tab, enter a new size and click **Expand**. Volumes only grow — you cannot shrink one. The disk expands in place — no redeploy needed.

### Take a snapshot

On the **Snapshots** tab, optionally name the snapshot and click **Take snapshot**. A snapshot is a manual point-in-time copy of the disk; leave the name blank and a timestamped one is generated.

Snapshots exist only for these web-service volumes — databases have no snapshots.

### Restore from a snapshot

Click **Restore** next to a snapshot and confirm. Restoring is destructive: it overwrites the volume's current data with the snapshot's, in place — same disk, same attachment — and the console asks you to confirm the data loss before it runs.

### Delete a snapshot

Click **Delete** next to a snapshot and confirm. This removes only the copy — the volume's live data is untouched.

## The environment's volumes list

The environment's **Volumes** page lists every volume — attached and detached — with its name, what it is attached to, its size, and its live state. **Manage** opens any volume's operations; **Delete** appears only on detached ones.

## Delete a volume

Only a detached volume can be deleted — detach it from its service first; the API rejects a delete while the volume is attached. There are two ways:

1. 
2.

> **Warning:**
>
> Deleting a volume permanently destroys the disk and everything on it — there is no undo. Moving a volume service to a different location also destroys the disk's data, because the disk is pinned to its location; the console asks you to confirm the loss before deploying. Detaching, by contrast, always keeps your data.
