Every GPU bills 730 hours a month. Most of them do nothing.
Run one read-only script against your cluster and see which GPUs are idle, which workloads could share a card, and how many nodes you could turn off. The report runs in your browser; your data stays with you.
The report
A rough number in ten seconds. Measured data from the scan replaces these guesses.
Drop gpu-snapshot.json to build the report.
Copy the summary as Markdown for a ticket or your manager. Send it to me and you get a reply with the three changes that save the most, free.
Three minutes, read-only, one JSON file.
Get the collector
A single Python file with no dependencies. Read it before you run it; it is shown in full below.
Run it
Allocation only, with the kubectl context you already use:
python3 gpu-waste-scan.py
Add utilization from dcgm-exporter through Prometheus:
kubectl -n monitoring port-forward \ svc/prometheus-operated 9090 & python3 gpu-waste-scan.py \ --prometheus http://localhost:9090 --window 7d
Load the result here
Open gpu-snapshot.json, check what it contains, then load it with Load snapshot above or drop it on the report.
Names are hashed by default. Pass --no-anonymize if you want to see your real workload names in the report.
Turn the report into a smaller GPU bill.
The scan tells you where the waste is. Fixing it means choosing between MIG, time-slicing, HAMi, Run:ai and DRA per workload, setting quotas people accept, and culling idle notebooks without losing anyone's work. That is the job.
Audit
- Read-only review of nodes, workloads, DCGM history and scheduling
- Per-workload decision: keep, share (and how), scale to zero, remove
- Sharing design for your GPUs and your scheduler
- Savings estimate you can take to finance
- One-hour walkthrough with your platform team
For clusters with 8 or more GPUs.
Sharing rollout
- HAMi, Run:ai/KAI Scheduler, MIG or time-slicing rolled out with your team
- Admission quotas and policy so the savings stay
- Idle culling for notebooks, scale-to-zero for serving
- Utilization dashboards and a runbook
Or 20% of the savings verified over the first six months.
GPU FinOps
- Monthly waste report from your own data
- Capacity review before every GPU purchase or commit
- Help when a new team or model lands
Cancel any month.
If the audit finds less than €2,000 a month in spend you can recover, you do not pay for it.
A fintech ML platform on one 8×H100 node
Every data scientist used to get a whole H100. I introduced HAMi memory slicing with admission-time quota checks, so a notebook asks for the memory it needs and the node stays shared. Same hardware, many more people working on it.
Questions
Healthy and unmeasured workloads keep their GPUs. Idle leftovers from batch jobs and Ray clusters are removed. Idle or underused workloads whose peak memory (plus 20% headroom) fits in half a card are packed onto shared GPUs, limited to 90% of memory and 100% of combined p95 compute. Pending GPU requests are added back to the pool they ask for (by node selector or affinity), or to the largest pool if they do not say. The result is rounded up to whole nodes, and every GPU beyond that is counted as recoverable.
Usually, but not always. DCGM utilization measures the share of time a kernel was running. A latency-sensitive service can sit at 5% and still need its own card, and a job can look idle while it waits on data. That is why the report shows actions as candidates and why the audit talks to the owners before anything changes.
H100 defaults to $6.88 per GPU-hour, the AWS p5 on-demand list price in October 2026. Other GPU types start from estimates marked in the table. Type your own rate per pool, including reserved or committed discounts, and every number updates.
Yes. Without metrics you still see unallocated GPUs and every workload holding a card, which is often enough to find a forgotten Ray cluster or a row of notebooks. Utilization-based actions need DCGM data; the NVIDIA GPU Operator installs dcgm-exporter by default.
The collector detects them and reports their slices. The report marks those pools as already shared and leaves them out of the savings math, because their allocation numbers count slices rather than cards.
Read-only. A ClusterRole with get and list on nodes and pods, and a read-only Prometheus endpoint or a Grafana export. The manifest is in the repository under rbac/; most teams approve it the same day. Nothing is changed in the cluster during the audit.
Nothing. There is no analytics script, no cookie and no form that sends data. The page's Content Security Policy forbids every outgoing request, which you can verify in your browser's network tab. Contact happens over email, on your initiative.
Yes. Prices are quoted in EUR; USD invoices at the day's rate are fine. Work runs on CET with overlap for US mornings, and invoices come from my registered sole proprietorship in Serbia under a standard services agreement.
I am Anatoly (Till) Lazarev, a platform and MLOps engineer in Novi Sad, Serbia, working with EU and US teams. Lazarev Cloud is my own practice: one engineer, not a company. The work comes from building and running a company ML platform on Kubernetes, Kubeflow, MLflow and KServe, with upstream fixes merged into MLflow along the way. More at lazarev.cloud.