# Disks
URL: https://metorial.com/docs/build/sandboxes/disks

Store data that outlives a machine, and grow a machine's storage.

---

Every machine comes with a writable root disk. Add more disks when data needs to outlive a machine, move between machines, or be copied for a new task.

<PageIntro>
  <Learn>
    * How the root disk works
    * How to create, attach, and detach disks
    * How to grow and copy a disk
  </Learn>

  <Reading title="Before you start">
    * [Run your first machine](/docs/build/sandboxes/quickstart)
  </Reading>
</PageIntro>

## The root disk [#the-root-disk]

Metorial creates a root disk for every machine. The machine's file system lives on it, so everything you install or write outside of attached disks ends up here. The root disk:

* Keeps its files when the machine pauses, hibernates, or restarts
* Is deleted together with the machine
* Can't be detached, deleted on its own, or copied
* Can grow with [`resize`](#grow-a-disk)

Find its ID in the machine's `root_disk` field, or list it with `metorial-admin sandbox disks list --type root_fs --machine-id $MACHINE`.

## Attach a disk [#attach-a-disk]

Disks you create yourself exist independently of machines. Delete a machine and its attached disks stay, ready for the next one.

<Steps>
  <Step title="Create a disk">
    Create the disk in the region your machine runs in. Sizes are in bytes; this one is 10 GiB.

    ```bash
    metorial-admin sandbox disks create --region iad1 --name workspace --size-bytes 10737418240
    ```

    Save the disk ID from the output as `DISK`.
  </Step>

  <Step title="Mount it into a machine">
    Pass the disk and a mount path in `mounts`, either when you create the machine or later:

    ```bash
    metorial-admin sandbox machines update $MACHINE \
      --mounts '[{"disk_id": "'$DISK'", "mount_path": "/data"}]'
    ```

    Mount changes apply when the machine restarts. A running machine restarts on its own; run `machines restart` to apply the change immediately.
  </Step>

  <Step title="Check the mount">
    ```bash
    metorial-admin sandbox machines shell $MACHINE -- df -h /data
    ```

    The machine's `mounts` field shows each disk with its mount path and whether it's mounted.
  </Step>
</Steps>

To detach a disk, update `mounts` without it. `mounts` replaces the whole list, so include every disk you want to keep.

<CodeBlockTabs defaultValue="TypeScript" groupId="language" mode="code">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="TypeScript">
      TypeScript
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="Python">
      Python
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="TypeScript">
    ```typescript
    let disk = await metorial.sandbox.disks.create({
      region: 'iad1',
      name: 'workspace',
      sizeBytes: 10 * 1024 ** 3
    });

    await metorial.sandbox.machines.update(machine.id, {
      mounts: [{ diskId: disk.id, mountPath: '/data' }]
    });
    ```
  </CodeBlockTab>

  <CodeBlockTab value="Python">
    ```python
    disk = metorial.sandbox.disks.create(
        region="iad1",
        name="workspace",
        size_bytes=10 * 1024**3,
    )

    metorial.sandbox.machines.update(
        machine.id,
        mounts=[{"disk_id": disk.id, "mount_path": "/data"}],
    )
    ```
  </CodeBlockTab>
</CodeBlockTabs>

## Grow a disk [#grow-a-disk]

Disks can grow but never shrink. Resizing briefly stops the machines the disk is mounted into, then starts them again.

```bash
metorial-admin sandbox disks resize $DISK --size-bytes 21474836480
metorial-admin sandbox disks resizes list $DISK
```

A resize moves through `pending`, `draining`, `resizing`, `verifying`, and `restarting` before it's `complete`. If it ends `failed`, retry it with `disks resizes retry $DISK <resize-id>`.

## Copy a disk [#copy-a-disk]

`clone` creates an independent copy of a disk in the same region. Use it to give several machines the same starting data, such as a prepared repository or dataset.

```bash
metorial-admin sandbox disks clone $DISK --name workspace-copy
```

<CodeBlockTabs defaultValue="TypeScript" groupId="language" mode="code">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="TypeScript">
      TypeScript
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="Python">
      Python
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="TypeScript">
    ```typescript
    let copy = await metorial.sandbox.disks.clone(disk.id, { name: 'workspace-copy' });
    ```
  </CodeBlockTab>

  <CodeBlockTab value="Python">
    ```python
    copy = metorial.sandbox.disks.clone(disk.id, name="workspace-copy")
    ```
  </CodeBlockTab>
</CodeBlockTabs>

## Find disks [#find-disks]

```bash
metorial-admin sandbox disks list --attached=false   # disks no machine uses
metorial-admin sandbox disks mounts list $DISK       # every machine the disk was mounted into
```

`disks list` also filters by `--type`, `--machine-id`, `--region`, and `--search`. A disk's `machine` field shows the machine it's attached to and its mount path.