> ## Documentation Index
> Fetch the complete documentation index at: https://docs.baseten.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Volumes

> Publish model weights and data once as immutable BDN volumes, and mount them read-only into any deployment.

<Note>
  Volumes are in **Private Preview**. [Contact Baseten](mailto:support@baseten.co)
  to request access.
</Note>

A volume is a named, versioned set of files that the [Baseten Delivery Network (BDN)](/development/model/bdn) delivers to your deployments. You publish a directory once, and every deployment that references it mounts the same files, read-only, wherever it runs. A volume does for model weights and data what a container image does for code.

## Versions, tags, and digests

A volume holds a series of sealed versions. When `baseten volume push` or `baseten volume sync` finishes, BDN commits the files as a new version and seals it. A sealed version never changes, and BDN identifies it by a digest of its contents, such as `bdn:weights/llama@b3:9f3c…`.

* **Namespace**: groups volumes in your organization, such as `weights`.
* **Volume**: one versioned collection of files, such as `llama`.
* **Version**: one sealed, immutable snapshot of the volume, identified by its digest.
* **Tag**: a mutable, case-sensitive name that points at one version, such as `prod`. Pushing with `--tag prod` moves the tag to the new version.
* **Head**: the volume's latest version. A reference with no tag or digest resolves to head.

Sealing makes volumes safe to depend on:

* **Reproducible deployments**: a deployment that mounts a digest gets the same bytes on every replica.
* **Small updates**: BDN splits files into chunks and stores each chunk once, so a new checkpoint that shares most of its bytes with the previous one uploads only the chunks that changed.
* **Fast starts**: deployments don't download the volume before they start. Data streams in as your model reads it.

## Volume references

Commands, API responses, and `config.yaml` all identify volumes with the same references:

| Form | Example | Resolves to |
| - | - | - |
| Volume | `bdn:weights/llama` | The volume's head version |
| Tagged version | `bdn:weights/llama:prod` | The version the tag points at |
| Immutable version | `bdn:weights/llama@b3:<hex>` or `bdn:weights/llama@<hex>` | One exact version |
| Path in a version | `bdn:weights/llama:prod/config.json` | One file or directory in the selected version |

A reference has the form `bdn:<namespace>/<volume>[@b3:<digest>|:<tag>]`, followed optionally by a path in the version. Every reference needs the `bdn:` prefix, a namespace, and a volume name. A digest can be the full value or a unique prefix of 12 to 64 hexadecimal characters. Copy digests from the `version_ref` that `baseten volume push`, `stat`, and `versions` return instead of typing them.

Namespace, volume, and tag names can be up to 256 characters and can't contain `/`, `..`, or null bytes. Namespace names are lowercase letters, digits, and hyphens, at least two characters long, and can't start with a digit. You can't name a namespace `namespaces` or `resolve`.

## How deployments resolve tags

When a deployment mounts a tag or a bare volume name, each replica resolves it when the replica starts and keeps that version for its lifetime. Moving the tag later doesn't change what running replicas serve, but new and scaled-up replicas mount the tag's new target. A deployment that mounts a tag can therefore serve two versions at once after a push.

Pin a digest in `config.yaml` so every replica serves the same files, and use tags to name versions for people.

## Requirements

* [Baseten CLI](/reference/cli/baseten/overview).
* To deploy with Truss, install [Truss](/reference/cli/truss/overview). The `baseten` CLI doesn't require Truss.
* A CPU instance or a GPU other than T4 or L4. BDN doesn't support volume mounts on T4 or L4 GPUs.

## Publish, mount, and deploy a volume

This walkthrough publishes a small directory as a volume, mounts it in a model, and deploys the model.

**To publish a volume and mount it in a deployment**:

1. Create a directory with a few files:

   ```sh theme={"system"}
   mkdir -p model-assets/config
   printf 'hello from a BDN volume\n' > model-assets/message.txt
   printf '{"revision": 1}\n' > model-assets/config/metadata.json
   ```

2. Push the directory as a new volume and tag the version `prod`. `push` creates the namespace and volume if they don't exist, and `--jq` prints the new version's immutable reference:

   ```sh theme={"system"}
   baseten volume push ./model-assets bdn:<namespace>/model-assets --tag prod --jq '.version_ref'
   ```

   Save the printed reference. The rest of this walkthrough calls it `<version-ref>`.

3. Inspect the published version:

   ```sh theme={"system"}
   baseten volume ls <version-ref> --recursive
   baseten volume cat <version-ref>/message.txt
   ```

4. Create a model directory named `volume-quickstart` with a `config.yaml` that mounts the version. Pinning the digest means later pushes can't change what this deployment mounts:

   ```yaml config.yaml theme={"system"}
   model_name: volume-quickstart
   python_version: py311
   resources:
     cpu: "1"
     memory: 2Gi
     use_gpu: false
   bdn:
     mounts:
       - source: <version-ref>
         path: /mnt/model-assets
   ```

5. Add a `model/model.py` that reads the mounted files:

   ```python model/model.py theme={"system"}
   import json
   from pathlib import Path


   class Model:
       def load(self):
           root = Path("/mnt/model-assets")
           self.message = (root / "message.txt").read_text().strip()
           self.metadata = json.loads((root / "config" / "metadata.json").read_text())

       def predict(self, model_input):
           return {"message": self.message, "metadata": self.metadata}
   ```

6. Deploy the model from the `volume-quickstart` directory:

   ```sh theme={"system"}
   baseten model push --wait --tail
   ```

7. Call the deployment with the predict URL from the push output:

   ```sh theme={"system"}
   curl -sS -X POST "<predict-url>" \
     -H "Authorization: Bearer $BASETEN_API_KEY" \
     -H "Content-Type: application/json" \
     -d '{}'
   ```

   The response includes the message and metadata read from the volume.

## Next steps

<CardGroup cols={2}>
  <Card title="Manage volumes" icon="layer-group" href="/development/volumes/manage">
    Publish new versions, roll back, and delete or restore versions.
  </Card>

  <Card title="Sync from remote sources" icon="cloud-arrow-down" href="/development/volumes/sync">
    Copy a Hugging Face repo or storage bucket into a volume.
  </Card>
</CardGroup>
