Skip to main content
A writeable volume that can be used to share files between one or more Modal functions. The contents of a volume is exposed as a filesystem. You can use it to share data between different functions, or to persist durable state across several instances of the same function. Unlike a networked filesystem, you need to explicitly reload the volume to see changes made since it was mounted. Similarly, you need to explicitly commit any changes you make to the volume for the changes to become visible outside the current container.

Usage

import modal

app = modal.App()
volume = modal.Volume.from_name("my-persisted-volume", create_if_missing=True)

@app.function(volumes={"/root/foo": volume})
def f():
    with open("/root/foo/bar.txt", "w") as f:
        f.write("hello")
    volume.commit()  # Persist changes

@app.function(volumes={"/root/foo": volume})
def g():
    volume.reload()  # Fetch latest changes
    with open("/root/foo/bar.txt", "r") as f:
        print(f.read())

Factory methods

Volume.from_name

modal.Volume.from_name(
    name: str,
    *,
    environment_name: Optional[str] = None,
    create_if_missing: bool = False,
    client: Optional[Client] = None,
) -> Volume
Reference a Volume by name, creating if necessary.
name
str
required
Name of the Volume.
environment_name
str
Environment to look up the Volume in.
create_if_missing
bool
default:"False"
Create the Volume if it doesn’t exist.
client
Client
Modal client to use.
volume
Volume
The Volume instance.
Example:
vol = modal.Volume.from_name("my-volume", create_if_missing=True)

Volume.from_id

modal.Volume.from_id(
    volume_id: str,
    client: Optional[Client] = None,
) -> Volume
Construct a Volume from an ID.
volume_id
str
required
ID of the Volume.

Properties

volume.name

volume.name -> Optional[str]
Name of the Volume, if it has one.

Methods

volume.commit

volume.commit()
Persist changes made to the volume. This must be called after writing files to make them visible to other containers. Example:
@app.function(volumes={"/data": volume})
def write_data():
    with open("/data/output.txt", "w") as f:
        f.write("results")
    volume.commit()

volume.reload

volume.reload()
Fetch the latest changes to the volume. This must be called to see changes made by other containers. Example:
@app.function(volumes={"/data": volume})
def read_data():
    volume.reload()
    with open("/data/output.txt", "r") as f:
        print(f.read())

volume.listdir

volume.listdir(
    path: str,
) -> list[FileEntry]
List files in a directory on the volume.
path
str
required
Path to list (can include glob patterns).
entries
list[FileEntry]
List of file entries.
Example:
entries = volume.listdir("/data")
for entry in entries:
    print(entry.path, entry.type, entry.size)

volume.read_file

volume.read_file(
    path: str,
) -> bytes
Read the contents of a file from the volume.
path
str
required
Path to the file.
contents
bytes
File contents.

volume.remove_file

volume.remove_file(
    path: str,
    *,
    recursive: bool = False,
)
Remove a file or directory from the volume.
path
str
required
Path to remove.
recursive
bool
default:"False"
If True, remove directories recursively.

volume.read_only

volume.read_only() -> Volume
Configure Volume to mount as read-only.
volume
Volume
New read-only Volume instance.
Example:
volume = modal.Volume.from_name("my-volume", create_if_missing=True)

@app.function(volumes={"/mnt/items": volume.read_only()})
def f():
    with open("/mnt/items/my-file.txt") as f:
        return f.read()

Manager methods

Volume.objects.create

modal.Volume.objects.create(
    name: str,
    *,
    allow_existing: bool = False,
    environment_name: Optional[str] = None,
    client: Optional[Client] = None,
) -> None
Create a new Volume object.
name
str
required
Name for the new Volume.
allow_existing
bool
default:"False"
If True, no-op when the Volume already exists.
Example:
modal.Volume.objects.create("my-volume")

Volume.objects.list

modal.Volume.objects.list(
    *,
    max_objects: Optional[int] = None,
    created_before: Optional[Union[datetime, str]] = None,
    environment_name: str = "",
    client: Optional[Client] = None,
) -> list[Volume]
Return a list of hydrated Volume objects.

Volume.objects.delete

modal.Volume.objects.delete(
    name: str,
    *,
    allow_missing: bool = False,
    environment_name: Optional[str] = None,
    client: Optional[Client] = None,
)
Delete a named Volume.
This deletes an entire Volume, not just a specific file. Deletion is irreversible.

Build docs developers (and LLMs) love