Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
"serverless/workers/deploy",
"serverless/workers/github-integration",
"serverless/storage/overview",
"serverless/development/volume-cache",
"serverless/development/dual-mode-worker"
]
},
Expand Down
1 change: 1 addition & 0 deletions serverless/development/optimization.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Optimization involves measuring performance with [benchmarking](/serverless/deve
|----------|--------|-------------|
| [Use cached models](/serverless/endpoints/model-caching) | ⬇️ Cold start (major) | Models on Hugging Face |
| [Bake models into image](/serverless/workers/create-dockerfile#including-models-and-files) | ⬇️ Cold start | Private models |
| [Cache files to a network volume](/serverless/development/volume-cache) | ⬇️ Cold start | Downloaded weights, attached volume |
| [Set active workers > 0](/serverless/endpoints/endpoint-configurations#active-workers) | ⬇️ Cold start (eliminates) | Latency-sensitive apps |
| [Select multiple GPU types](/serverless/endpoints/endpoint-configurations#gpu-configuration) | ⬆️ Availability | Production workloads |
| [Increase max workers](/serverless/endpoints/endpoint-configurations#max-workers) | ⬆️ Throughput | High concurrency |
Expand Down
93 changes: 93 additions & 0 deletions serverless/development/volume-cache.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
title: "Cache files to a network volume"
sidebarTitle: "Volume cache"
description: "Persist model weights and other files to an attached network volume to speed up Serverless worker cold starts."
---

import { ColdStartTooltip, WorkersTooltip } from "/snippets/tooltips.jsx";

The Runpod Python SDK includes a volume cache that persists files to an attached network volume and restores them the next time a worker starts. This reduces <ColdStartTooltip /> times, because a recycled worker can read cached files from the volume instead of downloading them again.

The volume cache is best-effort and self-contained. It caches the files a worker produces during startup (such as downloaded model weights) and never affects the outcome of a job. If any part of the cache fails, the worker falls back to a normal cold start.

## Requirements

- A [network volume](/storage/network-volumes#network-volumes-for-serverless) attached to your endpoint. The cache is stored on the volume, so nothing is cached when no volume is mounted.
- The Runpod Python SDK installed in your worker image. Endpoints built with recent versions of the SDK wire the volume cache into the worker loop automatically.

## How it works

The volume cache runs in two phases, tied to the <WorkersTooltip /> lifecycle:

- **Hydrate (on cold start):** Before the worker accepts any jobs, the cache extracts previously cached files from the network volume into their original locations. Hydration runs once per worker, and is skipped when the local files are already up to date.
- **Sync (after the first job):** After the worker completes its first successful job, the cache packs the files that changed during startup into a new archive and writes it to the volume. This runs in the background, so it doesn't delay your response.

Each worker writes its own archive, so multiple workers on the same endpoint can cache concurrently without overwriting each other. Cached files are stored under `.cache/<endpoint-id>/` on the network volume.

## Configure the volume cache

You configure the volume cache with environment variables set on your endpoint. See [Environment variables](/serverless/development/environment-variables) for how to set them in the Runpod console.

| Variable | Default | Description |
|----------|---------|-------------|
| `RUNPOD_VOLUME_CACHE` | Enabled | Controls whether the built-in volume cache runs. Set to `0`, `false`, or `no` to turn it off. |

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Env-var names, defaults, and gating come from runpod/serverless/utils/rp_volume_cache.py in PR #531: RUNPOD_VOLUME_CACHE defaults on (disabled only for 0/false/no), RUNPOD_VOLUME_CACHE_MAX_GB defaults to 50, and RUNPOD_CACHE_DIRS is split on os.pathsep (: on Linux). Used to write the configuration table.

Source: https://github.com/runpod/runpod-python/pull/531/files

| `RUNPOD_VOLUME_CACHE_MAX_GB` | `50` | Maximum total size, in gigabytes, of cached archives on the volume. When the cache exceeds this size, the oldest archives are pruned first. |
| `RUNPOD_CACHE_DIRS` | None | Additional directories to cache, beyond the model directories discovered automatically. Separate multiple paths with a colon (`:`), for example `/root/.cache:/workspace/models`. |

### Directories that are cached

By default, the volume cache targets the directories where Hugging Face and PyTorch store downloaded model weights:

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The auto-discovered cache directories (HF_HOME or ~/.cache/huggingface, plus HF_HUB_CACHE and TORCH_HOME when set) come from _discover_model_dirs() in rp_volume_cache.py. Used to write the "Directories that are cached" section.

Source: https://github.com/runpod/runpod-python/pull/531/files


- `HF_HOME` if set, otherwise `~/.cache/huggingface`.
- `HF_HUB_CACHE`, if set.
- `TORCH_HOME`, if set.

Add any other directories your worker downloads into at startup with `RUNPOD_CACHE_DIRS`.

## Use the cache directly

If you want explicit control over what gets cached and when, use the `VolumeCache` class from the Runpod Python SDK instead of relying on the built-in behavior. This is useful when your worker downloads files outside the automatically discovered directories, or when you want to cache files that aren't tied to the first job.

```python title="handler.py"
import runpod
from runpod.serverless import VolumeCache

cache = VolumeCache(["/workspace/models"])

def download_model():
# Download model weights into /workspace/models
...

# Hydrate from the volume, download only what's missing, then sync back
with cache.warm():
download_model()

def handler(job):
...

runpod.serverless.start({"handler": handler})
```

The `warm()` context manager hydrates the cache when the block is entered and syncs it when the block exits, so cached files are restored before your download runs and any new files are persisted afterward. You can also call `cache.hydrate()` and `cache.sync()` directly for finer control.

`VolumeCache` accepts the following arguments:

| Argument | Default | Description |
|----------|---------|-------------|

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The VolumeCache constructor signature and defaults (dirs, namespace defaulting to the endpoint ID, volume_path="/runpod-volume", max_size_gb=None, best_effort=True) and the public export runpod.serverless.VolumeCache come from rp_volume_cache.py and runpod/serverless/__init__.py in PR #531. Used to write the arguments table and code sample.

Source: https://github.com/runpod/runpod-python/pull/531/files

| `dirs` | Required | A list of directories to cache. |
| `namespace` | Endpoint ID | Groups cached archives on the volume. Defaults to the endpoint ID. |
| `volume_path` | `/runpod-volume` | Mount path of the network volume. |
| `max_size_gb` | Unlimited | Maximum total size of cached archives, in gigabytes. Oldest archives are pruned first. |
| `best_effort` | `True` | When `True`, cache errors are logged and swallowed instead of raised. |

## Limitations

- The cache is populated after the first successful job on a worker, and the write runs in the background. If a worker is recycled before the write finishes, that worker's contribution may not be cached until a later run.
- Automatic syncing applies to standard (non-streaming) handlers. Streaming handlers that yield results don't trigger the built-in sync, so use `VolumeCache` directly to cache files for those workers.
- Only regular files are cached. Symbolic links, hard links, and special files are skipped for safety.

## Next steps

- [Optimize your endpoints](/serverless/development/optimization): Combine the volume cache with other strategies to reduce cold starts.
- [Cached models](/serverless/endpoints/model-caching): Use Runpod's platform-level model cache for Hugging Face models.
- [Storage options](/serverless/storage/overview): Compare container disks, network volumes, and S3-compatible storage.
Loading