The cheapest GPU rental is not the one with the lowest hourly price. It is the smallest card that fits your job, rented for exactly as long as the job runs, with storage and idle time counted. This post gives you the method, a script that applies it to prices I copied from provider pages on 2026-10-09, and the fees that catch people out.
Treat every dollar figure here as a snapshot. GPU rental prices move, and the pages I read say as much. The method is the part that lasts.
Step 1: Work out how much memory the job needs
Do not pick a card by name. Estimate memory first with the VRAM calculator, which covers inference and LoRA/QLoRA training. Example estimates from it, all batch size 1:
- QLoRA on a 7B model, 1,024-token sequences: about 9.6 GB.
- bf16 LoRA on the same model: about 20.3 GB.
- QLoRA on a 32B model: about 27 GB.
- Serving a 4-bit 70B model with an 8,192-token context: about 47 GB.
Then keep 10 percent of the card unused. A 24 GB card is a 21.6 GB plan.
If the estimate fits a 16 GB card and the run is short, you may not need to rent at all; see Colab vs Kaggle vs paid GPUs.
Step 2: What do the providers list?
I read these public pricing pages on 2026-10-09 and copied on-demand, single-GPU rates. Hourly equivalents for Modal are its per-second rate times 3,600.
| Provider | GPU (VRAM) | Listed rate per hour | Note |
|---|---|---|---|
| RunPod pods | RTX A5000 (24 GB) | $0.27 | |
| RunPod pods | RTX 3090 (24 GB) | $0.50 | |
| RunPod pods | RTX 4090 (24 GB) | $0.89 | |
| RunPod pods | A40 (48 GB) | $0.59 | |
| RunPod pods | L40S (48 GB) | $1.09 | |
| RunPod pods | A100 (80 GB) | $1.79 | |
| RunPod pods | H100 SXM (80 GB) | $3.99 | |
| Lambda | A10 (24 GB) | $1.29 | 1-GPU instance |
| Lambda | RTX A6000 (48 GB) | $1.09 | 1-GPU instance |
| Lambda | A100 (40 GB) | $1.99 | 1-GPU instance |
| Lambda | H100 SXM (80 GB) | $4.29 | 1-GPU instance |
| Modal | T4 (16 GB) | about $0.59 | per-second billing |
| Modal | L4 (24 GB) | about $0.80 | per-second billing |
| Modal | A100 (80 GB) | about $2.50 | per-second billing |
| Modal | H100 | about $3.95 | per-second billing |
Where each number came from:
- RunPod (
runpod.io/pricing): the page said "Updated September 27, 2026". It has Community Cloud and Secure Cloud tabs, and my text extraction could not tell which tab the listed prices belong to, so check the tab before you rely on a number. - Lambda (
lambda.ai/pricing): self-serve instance prices, listed "plus applicable sales tax/VAT/GST". The same GPU is priced differently depending on how many GPUs are in the instance. For example the H100 SXM was listed at $3.99 in an 8-GPU instance and $4.29 in a 1-GPU one, so I used the 1-GPU rates. It also listed an A100 80 GB, but only in the 8-GPU configuration, so I left it out. - Modal (
modal.com/pricing): per-second rates for GPU tasks, plus a Starter plan with $30 a month of included compute. - Vast.ai (
vast.ai/pricing): a marketplace. The page says prices are set by supply and demand and shows no fixed list in the text I read, so I have no number for it. It describes three tiers: on-demand, interruptible ("50%+ cheaper", may be reclaimed) and reserved. Interruptible fits training only if you checkpoint often.
I did not include hyperscaler clouds, other GPU marketplaces or regional providers. Absence is not a judgement.
Step 3: Price the job with a script
This script needs vram_estimate.py from the calculator post. Edit the PRICES list when you re-read the pages, and replace the assumed hours with your own timing. I did not time any GPU run, so the hours here are placeholders, not measurements.
"""rent_cost.py: cheapest listed GPU that fits a job, and what the job costs. Needs vram_estimate.py in the same folder.
PRICES were copied from provider pricing pages on 2026-10-09. They WILL be stale. Re-read the pages, edit the list.
Modal bills per second: its per-second rate times 3600 is shown as an hourly equivalent.
"""
from vram_estimate import MODELS, train_gb, infer_gb
MODELS["qwen2.5-32b"] = dict(H=5120, L=64, nh=40, nkv=8, I=27648, V=152064, tied=False, bias=True)
# (provider, gpu, vram_gb, usd_per_hour)
PRICES = [
("RunPod pods", "RTX A5000", 24, 0.27), ("RunPod pods", "RTX 3090", 24, 0.50),
("RunPod pods", "RTX 4090", 24, 0.89), ("RunPod pods", "A40", 48, 0.59),
("RunPod pods", "L40S", 48, 1.09), ("RunPod pods", "A100 80GB", 80, 1.79),
("RunPod pods", "H100 SXM", 80, 3.99),
("Lambda", "A10", 24, 1.29), ("Lambda", "RTX A6000", 48, 1.09),
("Lambda", "A100 40GB", 40, 1.99), ("Lambda", "H100 SXM", 80, 4.29),
("Modal", "T4", 16, 0.000164 * 3600), ("Modal", "L4", 24, 0.000222 * 3600),
("Modal", "A10", 24, 0.000306 * 3600), ("Modal", "L40S", 48, 0.000542 * 3600),
("Modal", "A100 80GB", 80, 0.000694 * 3600), ("Modal", "H100", 80, 0.001097 * 3600),
]
USABLE = 0.9 # only plan to use 90% of a card's VRAM
# (label, estimated GB, hours you ASSUME; replace hours with your own timing)
JOBS = [
("QLoRA 7B, seq 1024", train_gb("qwen2.5-7b", "qlora", 1024), 3),
("bf16 LoRA 7B, seq 1024", train_gb("qwen2.5-7b", "lora", 1024), 3),
("QLoRA 32B, seq 1024", train_gb("qwen2.5-32b", "qlora", 1024), 6),
("Serve 70B Q4_K_M, 8k ctx", infer_gb("llama3.1-70b", "Q4_K_M", 8192), 10),
]
for label, need, hours in JOBS:
print(f"\n{label}: needs ~{need:.1f} GB, assumed {hours} h")
shown = set()
for prov, gpu, vram, price in sorted(PRICES, key=lambda r: r[3]):
if need <= vram * USABLE and prov not in shown:
shown.add(prov)
print(f" {prov:12s} {gpu:10s} {vram:3d} GB ${price:5.2f}/h -> ${price * hours:6.2f}")
Real output (the script needs the qwen2.5-32b line because the calculator ships without that model):
QLoRA 7B, seq 1024: needs ~9.6 GB, assumed 3 h
RunPod pods RTX A5000 24 GB $ 0.27/h -> $ 0.81
Modal T4 16 GB $ 0.59/h -> $ 1.77
Lambda RTX A6000 48 GB $ 1.09/h -> $ 3.27
bf16 LoRA 7B, seq 1024: needs ~20.3 GB, assumed 3 h
RunPod pods RTX A5000 24 GB $ 0.27/h -> $ 0.81
Modal L4 24 GB $ 0.80/h -> $ 2.40
Lambda RTX A6000 48 GB $ 1.09/h -> $ 3.27
QLoRA 32B, seq 1024: needs ~27.0 GB, assumed 6 h
RunPod pods A40 48 GB $ 0.59/h -> $ 3.54
Lambda RTX A6000 48 GB $ 1.09/h -> $ 6.54
Modal L40S 48 GB $ 1.95/h -> $ 11.71
Serve 70B Q4_K_M, 8k ctx: needs ~46.9 GB, assumed 10 h
RunPod pods A100 80GB 80 GB $ 1.79/h -> $ 17.90
Modal A100 80GB 80 GB $ 2.50/h -> $ 24.98
Lambda H100 SXM 80 GB $ 4.29/h -> $ 42.90
What to take from it: a memory-fit rule, not a price rule, picks the card. The 7B QLoRA job needs under 10 GB, so a 24 GB card is already generous. The 70B inference job just misses a 48 GB card (46.9 GB estimated against a 43.2 GB plan), which pushes it to 80 GB cards and roughly doubles the hourly rate. Shaving the context or using a lower-bit file can change that tier.
Step 4: Add the costs the hourly rate hides
These came from the same pricing pages:
- Storage. RunPod listed container disk at $0.10 per GB per month, and volume disk at $0.10 per GB per month while running and $0.20 while idle. A 100 GB volume left idle for a month is therefore about $20, which can exceed the compute bill for a short experiment.
- Idle billing. Modal's FAQ says it bills during application load time and processing, and by default keeps containers alive 60 seconds after the last input, which is also billed. With pods, the clock runs until you stop them. Forgetting a pod overnight at $1.79 an hour is about $43 for 24 hours.
- Surcharges on the headline rate. Modal's comparison table lists region selection at 1.15 to 1.75 times base prices and non-preemptible execution at 3 times base prices.
- Egress. Modal lists network egress at $0.04 per GiB beyond included usage. Check egress terms before you download many large checkpoints.
- Tax. Lambda says its rates are plus applicable tax.
- Data transfer time. Downloading a 15 GB base model onto a fresh machine is time you pay for. Cache it on a persistent volume if you will come back.
Free allowances help at the small end. Modal's Starter plan lists $30 per month of included compute, so a few hours on a small GPU may cost nothing. That is a current offer on their page, not a promise it stays.
When should I not rent a GPU?
- A hosted API already does the job. You pay per token and manage nothing. Run the API cost worked examples for your volume before assuming self-hosting is cheaper.
- The job fits a laptop. See the laptop memory guide.
- You need data to stay on your machine. Rented machines are someone else's hardware. The local vs cloud privacy guide lists what to check.
- You are still debugging the script. Debug on a small model locally or on a free tier, and rent only for the final run.
- You need an always-on server. That is a different calculation; a CPU VPS may cover it. See the VPS review if the work is orchestration rather than GPU inference.
A short checklist before you press deploy
- Memory estimate done, with 10 percent spare.
- Hours estimated from a timed 20-step trial, not a guess.
- Checkpoints saved to a volume or bucket, and a resume command tested.
- A stop plan: who stops the machine, and when (set an alarm).
- Storage deleted after the run.
- Current prices re-read on the provider's page today.
What I could not verify
- RunPod's tab (Community or Secure) for the listed prices; Vast.ai's current marketplace prices; availability of any listed GPU at the time you try to rent it.
- Real run times. I have no GPU, so every "hours" value is an assumption.
- Hyperscaler, Indian-region and other providers. I did not check them.
- Whether any price still stands by the time you read this. Re-read the page.



