getvram gives every container a VRAM grant. Tenant A exceeds it and gets a local OOM. Tenant B keeps serving. The runtime is MIT. The cut is commercial.
# Before getvram: choose ONE container to use the GPU services: llm: image: ollama/ollama # ❌ Consumes ALL 8 GiB — other containers OOM-killed deploy: resources: reservations: devices: - driver: nvidia capabilities: [gpu]
# After: every service gets exactly what it needs services: llm-inference: image: ollama/ollama runtime: vram labels: vram.limit: "6144m" # ✅ 6 GiB grant vram.priority: "high" embedder: image: my-embedder runtime: vram labels: vram.limit: "1024m" # ✅ 1 GiB, auto-burst if idle training: image: pytorch/pytorch runtime: vram labels: vram.limit: "2048m" # ✅ 2 GiB, BestEffort QoS vram.priority: "low"
Container A grabs all 8 GiB. Container B crashes with CUDA out of memory. You kill A. You restart B. Repeat.
nvidia-container-toolkit, CUDA versions, WSL2 passthrough, MPS server setup. Hours of config before you write a single line of model code.
Your GPU sits at 5% utilization while your LLM waits between requests. Every other container is blocked waiting for it to finish.
One misbehaving container corrupts shared GPU state. MPS offers no memory isolation — a crash in one process can kill the entire GPU context.
getvram doesn't sit between your container and the GPU as a proxy. It speaks directly to the CUDA Driver API at the GPU MMU level — the same abstraction layer used by NVIDIA's own virtual GPU (vGPU) products.
At startup, cuMemAddressReserve carves a virtual address space equal to your total GPU VRAM. No physical memory is allocated yet.
When a container registers (via OCI hook), cuMemCreate allocates a physical VRAM block sized to that container's quota. The handle is transferable across process boundaries.
cuMemMap + cuMemSetAccess binds each physical handle to a unique virtual address slice per container. Container A's GPU pointers are completely disjoint from Container B's — enforced at the hardware MMU.
When a container is idle, its physical pages can be remapped to a bursting container in microseconds. No data movement. No kernel panic. One cuMemUnmap + cuMemMap.
| Feature | NVIDIA MPS | NVIDIA MIG | Time-Slicing | getvram |
|---|---|---|---|---|
| Memory isolation | ❌ None | ✅ Physical | ❌ None | ✅ VA-level (MMU) |
| Dynamic resizing | ❌ Static | ❌ Requires reconfiguration | ⚠️ Burst only | ✅ Hot-resize in μs |
| Supports any CUDA version | ✅ | ⚠️ A100/H100 only | ✅ | ✅ Pascal+ |
| Works in Docker Desktop | ❌ | ❌ | ❌ | ✅ Linux Docker · vram run on Mac |
| Per-container OOM kill | ❌ Cascade | ✅ | ❌ | ✅ Isolated |
| Configuration required | MPS server setup | Hardware + profile | Driver flag | Zero — docker labels |
| Apple Silicon (M-series) | ❌ | ❌ | ❌ | ✅ Metal MTLHeap (v2) |
Software license, one node. Not SaaS. Not a cluster product. Kubernetes is not for sale because it is not built.
vram commandvram.limit=4g)vram init writes a compose file for OllamaThe number is a label. Nobody enforces it. A greedy neighbor can still take the card.
GitHubvram runLicense for that machine. We don't keep your GPU or your models.
Buy with Stripe →Or mail hello@getvram.com if checkout is down.
With --gpus all they share the device, not the memory. The first cudaMalloc often takes the card. The second dies with CUDA OOM. getvram gives each container a VRAM ceiling. Over that ceiling is a local OOM. The neighbor keeps generating.
vram.limit?No. docker-vram is the runtime and CLI. Containers start. Labels are recorded. There is no daemon in that repo. Enforcement is the paid getvram grant on your machine.
Docker Desktop is a Linux VM. Host Metal cannot see those containers. On Apple Silicon use vram run --limit=1g -- ollama serve. Unified memory: the product is the quota, not a cascade OOM onto a neighbor.
No. You install it on hardware you already own. We do not rent GPUs and we do not host your models.
Leave your email if you want the cut on your card. The MIT runtime is already on GitHub. We do not rent GPUs.