Kaggle Notebook Lost Its GPU? A Diagnostic Guide to Quota, Session Caps, and OOM Kills
A four-check order of operations for the ways Kaggle compute fails — weekly GPU quota, session caps, idle timeouts, and OOM kills — plus a checkpoint pattern that makes long jobs survive ephemeral sessions.
21 Apr 2026, 09:04 UTC

Your notebook trained on GPU last week. Today it crawls along on CPU, the accelerator dropdown is greyed out, or the session dies six hours into a run with no traceback. On Kaggle's free compute tier, this is almost never a code bug. It is one of four resource failures: weekly GPU quota exhaustion, the per-session runtime cap, an idle timeout, or an out-of-memory kill that only looks like a quota problem.
The takeaway: four ordered checks resolve most cases in a few minutes, and the durable fix is to stop treating a Kaggle session like a persistent machine. Long jobs should be resumable pipelines that checkpoint to disk, because every session — however healthy — will eventually end.
What the failure looks like
The recognizable condition is a notebook that previously used the GPU and now shows at least one of these: the accelerator selector in the notebook's right-hand panel is disabled or missing GPU options; the code runs without errors but device logs report CPU; a committed run stops cleanly after many hours; an interactive session ends after you left it alone; or the worker dies partway through loading a large dataset.
Cause and diagnostic table
| Symptom | Likely cause | Fastest confirmation |
|---|---|---|
| GPU/TPU options greyed out in the accelerator selector | Weekly GPU quota exhausted | Quota meter in account settings shows zero remaining |
| Notebook runs, no errors, but training is far slower than before | Session attached as CPU-only (selector reset, or quota ran out between sessions) | Device smoke test prints False (see Check 1) |
| Session stops cleanly after roughly 9–12 hours of wall time | Per-session runtime cap | Compare elapsed time against the documented cap for your accelerator |
| Interactive session ends after a period of inactivity | Idle timeout | Last interaction was hours before the session ended |
| Worker killed during a large data load; log ends abruptly, no Python traceback | Host RAM exhaustion (OOM kill), not quota | RAM meter pinned near maximum just before the death |
Four checks, in order
Check 1: Is a GPU actually attached?
Run this in the first cell, before any heavy work. It is read-only and costs nothing:
import torch
print('cuda available:', torch.cuda.is_available())True means the accelerator is attached; False means the session is CPU-only and the rest of your debugging should move to Checks 2 and 3. For TensorFlow, use tf.config.list_physical_devices('GPU'). This check exists because a CPU-only session produces no error — it just runs slowly, which is easy to misread as a data or model problem.
Check 2: How much GPU quota remains?
Open your account settings on kaggle.com and read the accelerator usage display. Kaggle has historically allotted on the order of 30 GPU hours per week, but the exact figure varies by accelerator and has changed over time — read your own meter rather than trusting any article, including this one. Two details cause most misdiagnoses here. First, the quota resets weekly, not daily, so a failure that persists all day is not 'waiting it out' material. Second, GPU access has historically been tied to phone verification, so an unverified account may lack GPU options for reasons unrelated to usage.
Check 3: How long did the session run?
If the session stopped cleanly after many hours, compare the elapsed wall time to Kaggle's per-session cap, which has sat in the roughly 9–12 hour range depending on accelerator and account tier (verify the current figure — these caps change). Distinguish this from the idle timeout: the runtime cap kills a session at a fixed wall-clock limit regardless of activity, while the idle timeout kills an interactive session that has gone untouched. A committed 'Save & Run All' job that dies at hour ten is a cap, not neglect.
Check 4: Did memory kill the worker?
Watch the RAM and disk meters in the notebook sidebar during the run. An out-of-memory kill on the host typically ends the log abruptly — a killed process, not a Python traceback — and often happens while loading a large dataset. This is frequently mistaken for quota exhaustion because both 'just stop' the notebook. Note the difference from GPU-side OOM, which raises a normal CUDA out-of-memory exception you can catch; that is a batch-size problem, not a session problem.
Fixes matched to the finding
Quota exhausted
The goal is fewer GPU-hours per experiment, not faster code. Prototype and explore data on CPU, and attach the GPU only for training. Subsample during development, shorten epochs, and move preprocessing and augmentation off the GPU — do them once, cache the result, and reuse it across runs. Mixed-precision training, where your framework supports it, reduces GPU time per epoch. TPUs have historically carried a separate quota, so a TPU can be a fallback for compatible workloads.
Runtime cap reached
Split the job. Checkpoint model, optimizer, and epoch state to /kaggle/working (the only writable directory — /kaggle/input is read-only), then resume in a fresh session. The pattern is in the next section.
Idle timeout
Do not fight it with keep-alive tricks. For long jobs, use committed batch runs instead of babysitting an interactive session; the job runs headless to completion or to the cap, whichever comes first.
Host OOM
Reduce peak memory: smaller batches with gradient accumulation, memory-mapped or streaming data loading instead of loading everything up front, and deleting large intermediates as soon as they are consumed.
The engineering decision: treat sessions as ephemeral
The durable fix for every cap-related failure is the same: design the job as a resumable pipeline. A minimal PyTorch pattern (illustrative — adapt and test it against your own loop before relying on it):
import os, torch
CKPT = '/kaggle/working/last.pt'
def save_checkpoint(model, optimizer, epoch):
torch.save({
'epoch': epoch,
'model': model.state_dict(),
'optimizer': optimizer.state_dict(),
}, CKPT)
def resume(model, optimizer):
if os.path.exists(CKPT):
ck = torch.load(CKPT, map_location='cpu')
model.load_state_dict(ck['model'])
optimizer.load_state_dict(ck['optimizer'])
return ck['epoch'] + 1
return 0
start = resume(model, optimizer)
for epoch in range(start, NUM_EPOCHS):
train_one_epoch(epoch)
save_checkpoint(model, optimizer, epoch)For training that spans multiple sessions, the standard Kaggle pattern is to commit a run that ends at a checkpoint, then start the next run with that version's output attached as an input dataset and load the checkpoint from there. The exact UI wording for attaching a notebook's output changes over time, so verify the current steps in Kaggle's documentation before building a multi-day pipeline around it. Also save and restore RNG state if you need runs to be reproducible across resumes.
When to escalate instead of debugging
Stop debugging code and report the problem when: your quota meter shows remaining hours but the GPU still will not attach; sessions die well before the documented cap with no OOM evidence; or accelerator options are missing entirely on an account you know is verified. These point at the platform, not your notebook. Report through Kaggle's official feedback and forum channels, including the time of the failure, the accelerator selected, and what the quota and RAM meters showed. Do not keep retrying — retries burn quota you may need later.
Limitations and how to verify
Every number in this guide — the weekly allowance, the 9–12 hour cap range, the reset schedule, the phone-verification requirement — is version-sensitive and has changed before. Treat the figures as orientation, not specification. To verify on your own account: confirm which accelerator options are selectable in a notebook's panel; read consumed versus allotted GPU hours from your settings page; run the Check 1 smoke test to confirm actual device placement; and deliberately run a small training job that checkpoints in one session and resumes in a second, proving the resumable pattern works before you depend on it for a real run.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.