1---
2title: Volumes
3description: A disk in one region, attached to one Machine.
4---
5
6A Fly Volume is a disk in one [region](/fly/compute/regions),
7attached to one Machine.
8Minimum size is 1 GB. Machines can be replaced. The Volume keeps
9the data.
10
11There is no standalone Volume resource. Create disks with
12[`MountVolume`](/providers/fly/mountvolume) or Machine `mounts`.
13
14Fly cannot share one Volume across two Machines. `count: 3` creates
15three Volumes in one name-group, one per replica.
16
17## Mount into a Service
18
19Inside a [Service](/fly/compute/services)'s constructor, bind a disk to a
20path and use it as a plain directory at runtime. App and region come
21from the parent Service:
22
23```typescript
24export default class Api extends Fly.Service<Api>()(
25 "Api",
26 { main: import.meta.url, region: "iad", count: 3, port: 3000 },
27 Effect.gen(function* () {
28 const disk = yield* Fly.MountVolume({ path: "/data", sizeGb: 1 });
29 const fs = yield* FileSystem.FileSystem;
30
31 return {
32 fetch: Effect.gen(function* () {
33 const text = yield* fs.readFileString(`${disk.path}/hello.txt`);
34 // ...
35 }),
36 };
37 }).pipe(Effect.provide(Fly.MountVolumeLive)),
38) {}
39```
40
41At deploy time the binding writes `{ path, sizeGb }` into the
42Service. Reconcile creates one Volume per replica and writes
43`config.mounts`. At runtime you get `disk.path`.
44
45`sizeGb` can **grow in place** via `extendVolume` — shrinking is
46not supported (Fly cannot shrink a Volume). Encryption and
47filesystem type are create-only.
48
49If a replica Machine is replaced, its Volume re-attaches on the next
50deploy — the data rides along.
51
52## Attach from a Machine
53
54For a raw Machine, pass `mounts` on the resource. App and region are
55the Machine's:
56
57```typescript
58const box = yield* Fly.Machine("Box", {
59 app: Site,
60 region: "iad",
61 image: "postgres:16",
62 mounts: [{ path: "/data", sizeGb: 10 }],
63});
64```
65
66Resolved attrs expose `mounts` (replica 0) and `replicas[i].mounts`
67(every replica's `volumeId` / `sizeGb` / group `name`).
68
69## Snapshots
70
71Scheduled snapshots default on (`autoBackupEnabled`). Snapshot
72retention updates in place. An on-demand snapshot is
73[`VolumeSnapshot`](/providers/fly/volumesnapshot) — create is
74fire-and-forget; destroy is a no-op (snapshots follow Volume
75retention). Point it at a Volume id from the parent Machine or
76Service:
77
78```typescript
79export const Nightly = Fly.VolumeSnapshot("Nightly", {
80 app: Site,
81 volumeId: box.mounts[0].volumeId,
82});
83```
84
85Restore into a new disk with `snapshotId` on the mount (create-only):
86
87```typescript
88const restored = yield* Fly.Machine("Restored", {
89 app: Site,
90 region: "iad",
91 image: "nginx:alpine",
92 mounts: [{ path: "/data", sizeGb: 1, snapshotId: Nightly.snapshotId }],
93});
94```
95
96## Where next
97
98- [Tutorial part 3](/fly/tutorial/part-3) — mount a disk into a
99 Service step by step.
100- [Services](/fly/compute/services) — `count` and `MountVolume`.
101- [`MountVolume` reference](/providers/fly/mountvolume) and
102 [`VolumeSnapshot` reference](/providers/fly/volumesnapshot).