Skip to content
OpenRelay is in early access, and the /v1 API is stable. New capabilities ship in the changelog.
GuidesCompute

Pods and persistent storage

Bring-your-own-container GPU pods, what survives a stop, restart, crash or node loss, and how the /workspace volume is billed and retained.

A pod runs your container image on one or more whole GPUs of a single node, with SSH access and an HTTPS endpoint. Every pod comes with a persistent volume mounted read-write at /workspace. That volume is what makes a pod safe to stop and start: your data lives there, not in the container filesystem.

What persists

LocationSurvives a stop, restart or crash?Survives delete?
/workspace (the volume)YesNo
Everything else in the containerNo: the container is recreated from the imageNo

Put checkpoints, datasets, notebooks and anything you cannot re-download under /workspace. Package installs, files written elsewhere and running processes are gone whenever the container is recreated.

Volume size

Pick the size when you create the pod (volumeGb): the default is 50 GB, the range is 10 to 1024 GB. The size is fixed for the pod's life; there is no resize. The volume lives on the pod's node, is not billed separately and adds nothing to the hourly rate.

The pod page in the dashboard shows how much of the volume is in use. The figure comes from an hourly report by the node, so it can lag by up to an hour.

Creating a pod

In the dashboard, Pods > New pod has a field for the volume. From the CLI or the API, pass --volume-gb / volumeGb (omit it for 50 GB):

orl pods create \
  --image ghcr.io/you/trainer:latest \
  --gpu-model-id <gpuModelId from orl pods capacity list> \
  --gpu-count 1 \
  --volume-gb 200 \
  --ssh-key-ids <sshKeyId from orl ssh-keys list> \
  --name trainer

The same request as an API call is POST /v1/pods. GET /v1/pods/capacity lists the GPU models with free capacity and their rates.

A pod is reachable by the keys you attach to it

sshKeyIds is required and names SSH keys registered on your organization (the SSH Keys page in the dashboard, orl ssh-keys create, or POST /v1/orgs/{orgId}/ssh-keys/create). The SSH gateway accepts only the org keys attached to the pod; a key registered on your organization but not attached to it is rejected, with no organization-wide fallback. Attach or detach a key later from the pod's Settings tab; the change takes effect within about a minute, with no restart. Troubleshoot SSH connections covers the errors a rejected key produces.

When a create is refused

A create that is refused says why in its status and code:

StatusCodeMeaningWhat to do
503INSUFFICIENT_GPU_CAPACITYNo node has gpuCount GPUs of the model free for you right now. A pod's GPUs all come from one node, so free GPUs spread across nodes do not add up.Pick another GPU model or a smaller gpuCount, or try later. maxGpuCount on GET /v1/pods/capacity is the largest pod a create can take now.
503INSUFFICIENT_HOST_CAPACITYThe nodes that fit cannot size a pod's RAM and CPU yet, usually because they are being brought up and have not reported their host inventory.Try again in a few minutes.
503INSUFFICIENT_IP_CAPACITYNo free guest network address, or for an InfiniBand pod no free address on the node's fabric.Terminate unused workloads, or try later.
400GPU_COUNT_NOT_ALLOCATABLENo node could ever hold gpuCount GPUs of the model for your organization.Lower gpuCount. Retrying unchanged will not help.
409FEATURE_DISABLEDPods are not enabled for your organization.Contact support.
409CONFLICTYour organization's SSH keys kept changing while the pod was being created. Nothing was created.Retry.
400POD_ADMISSION_FAILEDThe request cannot be placed as sent: a missing gpuModelId, an invalid environment variable, a model with no pod price, or a shmSizeGb or volumeGb above what the chosen node gives a pod of this size. The message names the field.Fix the request.
400INVALID_ARGUMENTA missing image, a gpuCount outside 1 to 8, or an unknown computeClass.Fix the request.
400COMPUTE_CLASS_RETIREDcomputeClass is interruptible, which is retired.Send on_demand, or omit the field.
400SSH_KEYS_REQUIREDsshKeyIds is empty.Attach at least one SSH key registered on your organization.
400BAD_REQUESTsshKeyIds names a key that is not on your organization, or lists more than 64 keys.Fix the key list.

A 503 is a capacity refusal: the request is valid and can succeed once capacity frees up, but sending it again in a tight loop will not make room. orl pods create exits 7 on a 503 and 6 on a 409.

AMD pods

AMD Instinct pod hosts run ROCm on the amdgpu driver. Volume, SSH, lifecycle and billing work exactly as above; what changes is the image.

The image has to match the GPU vendor. A CUDA image on an AMD GPU, or a ROCm image on an NVIDIA GPU, starts a pod whose container cannot see its GPU: torch.cuda.is_available() comes back false and you are billed for the pod anyway. The dashboard blocks the mismatch before you deploy. The API and the CLI do not, so check the image yourself when you create a pod with orl or POST /v1/pods.

Images that work on AMD:

ImageNotes
rocm/dev-ubuntu-22.04:7.2.4ROCm 7.2, validated end to end on our hardware
rocm/pytorch:rocm7.2.4_ubuntu22.04_py3.10_pytorch_release_2.10.0PyTorch on ROCm

A pod gets whole GPUs. Each one is granted as /dev/kfd plus that GPU's render node, so rocm-smi inside the container lists exactly the pod's GPUs and nothing else. Run it first thing after you SSH in (nvidia-smi on an NVIDIA pod) to confirm the container sees what you paid for.

What AMD pods do not do yet

No InfiniBand or RDMA. One OAM module is one GPU: compute partitions (CPX, DPX, QPX) are not sold, so an eight-module AMD node sells eight GPUs.

Lifecycle

A pod moves through the statuses below. Only running is billed.

StatusMeaningBilledGPU held/workspace
deployingBeing placed, or being started againNoYesKept
runningServingYesYesKept
stoppedYou stopped it; the GPU is releasedNoNoKept
interruptedThe node became unreachable; the pod resumes on its own when the node returnsNoYesKept
terminatedDeletedNoNoDeleted

Stop and start

Stop (POST /v1/vms/{id}/stop, orl vms stop) ends the container, releases the GPU and keeps the volume. You are not billed while the pod is stopped.

Start (POST /v1/vms/{id}/restart, orl vms restart on a stopped pod) brings it back on the same node, because that is where the volume is. The GPUs it needs must be free on that node; if another workload has taken them the start is refused with 503 POD_NODE_BUSY, and you can try again later or delete the pod and create a new one elsewhere. An InfiniBand-enabled pod whose fabric has no free address is refused the same way, with 503 INSUFFICIENT_IP_CAPACITY (capacity refusals). A start while the node is offline is refused with 409 POD_NODE_OFFLINE, and a start of an InfiniBand-enabled pod on a node whose agent is still being updated for it with 409 POD_NODE_NO_INFINIBAND. A start of an AMD GPU pod on a node whose agent is below the level that grants AMD GPUs is refused with 409 POD_NODE_NO_AMD_GRANT until the provider updates the agent.

Restart while running

The same restart call on a running pod recreates the container from the image (a fresh filesystem outside /workspace) and keeps the volume. Billing continues through the restart.

Crashes and node loss

If the container exits or is killed, the pod is recreated automatically on the same node with the volume intact, and the pod stays running.

If the node stops reporting to us, the pod becomes interrupted after a few minutes of grace: billing stops, the volume and the GPU reservation stay with the node, and the pod returns to running by itself once the node is back. You can also stop or delete an interrupted pod.

Delete

Delete (POST /v1/vms/{id}/terminate, orl vms terminate) removes the pod and its volume. There is no undo and no snapshot: copy anything you need out of /workspace first.

Retention: when a volume is deleted without you asking

Two situations delete a pod and its volume automatically. Both send an email first.

  • Node never came back. An interrupted pod whose node has not returned within 7 days is deleted. If the node is removed from the platform before that, the pod is deleted at that point, because the volume was on the box.
  • Insufficient balance. When your available balance drops below $0.50, running pods are stopped and kept with their volumes. If the account is not funded again within 7 days of that stop, those pods and their volumes are deleted. Top up before then and start them again.

A pod you stopped yourself is kept, with its volume, until you delete it.

Billing

A pod bills the GPU rate shown at create for every second it is running, as one usage record per running stint (create to stop, start to interrupt, and so on). Stopped and interrupted time is free. The volume has no charge of its own. See VM billing for how rates, balance and auto-stop work; the same rules apply to pods.

On this page