Files that come back
Whatever is in /kaggle/working when a session ends returns at the next start, however it ended. Kaggle keeps the files; kdev puts back the symlinks, empty folders and exec bits it drops, so a virtualenv survives.
One command starts a GPU box you can ssh into or open in VS Code. Leave whenever you like: your files are there next time, on any account in your Kaggle group, from any machine.
Kaggle's API can save a notebook and run it. It has no "give me a shell" call. kdev adds that, then fixes what makes a notebook a bad place to keep work.
Whatever is in /kaggle/working when a session ends returns at the next start, however it ended. Kaggle keeps the files; kdev puts back the symlinks, empty folders and exec bits it drops, so a virtualenv survives.
Each account in your Kaggle group brings 30 GPU-hours and 20 TPU-hours a week to the same notebook. When one runs short, kdev up asks which takes over.
Pick the accelerator once and every kdev up uses it. The box runs Kaggle's own image with 934 packages already installed and the internet switched on, so pip, apt and git work as usual.
$ kdev config set gpu t412h sessions · 30 GPU-hours a weekUbuntu 22.04 · CUDA 12.8 · 934 packages preinstalled
The box is a host called kaggle in ~/.ssh/config. Open a folder, install extensions, debug on the GPU.
Both ends dial out to Cloudflare and meet at a hostname that never changes. Public-key auth only.
Set git-remote and the box clones it at boot, pushes every 15 minutes and once more at teardown.
kdev forward 8888 puts Jupyter, TensorBoard or your API on localhost, with a clear error if nothing listens.
Every open shell hears about it 15 and 5 minutes before the session runs out.
status, history, account and workspace files speak --json. Every prompt has a flag; NO_COLOR is honoured.
The simple picture is on the right. When you want every module, file and API call, open the full architecture.
Kaggle starts every batch session with an empty /kaggle/working. kdev finds the version you left off at, and the new box downloads it before you connect. Eight ways a session ends, each measured.
What the next kdev up gives you
Everything
It stops early and hands the quota back. Kaggle keeps /kaggle/working as that version's output.
What the next kdev up gives you
Everything
kdev up notices the save is still running, waits for it (about 2 minutes per GB), then builds on it.
What the next kdev up gives you
Everything
A cancel still saves. Measured, not assumed.
What the next kdev up gives you
Everything
The box stops itself before Kaggle’s deadline, so the save always fits in the session.
What the next kdev up gives you
Everything
The cell notices cloudflared exit, records metadata, and ends the run cleanly, so it saves like any other.
What the next kdev up gives you
Everything, up to the crash
File contents are never lost. Symlinks, empty folders and exec bits are recorded every 30 seconds, so a hard kill costs at most that much metadata.
What the next kdev up gives you
Not testable
kdev can't simulate this one. A git-remote is the copy that survives: the box commits and pushes every 15 minutes.
What the next kdev up gives you
Nothing ended
The box keeps running on Kaggle. kdev up, from any account or machine, connects to it instead of starting another.
$ kdev setupSSH key, cloudflared, Kaggle sign-in, workspace, tunnel. Only what is missing.
$ kdev upStarts the box, or connects to the one already running.
$ ssh kaggleOr VS Code → Remote-SSH → kaggle. Leave whenever you like.
$ kdev downStop early and hand the quota back. Files are saved anyway.
kdevThe overview: the box, every account’s quota, the workspace, then a menu of what makes sense now.
$ kdevkdev upStart the box, or connect to the one already running from any account or machine.
--gpu--hours--account--open--no-restore--replace-y
$ kdev up --gpu t4 --hours 9kdev sshA shell on the box. Pass a command after --; ssh's exit code is kdev's.
-- ARGS
$ kdev ssh -- python train.pykdev forwardnext releaseForward localhost ports to services on the box, with a clear error if one is taken or nothing listens.
PORTLOCAL:REMOTE
$ kdev forward 8888 9000:6006kdev statusRunning? Who started it, when it ends, whether it answers, and the restore state.
--json
$ kdev status --jsonkdev logsWhat the box itself is saying: the session log, without the kernel’s noise.
-n N--all
$ kdev logs -n 50kdev downStop the box now. It saves /kaggle/working however it stops; cancels as the starting account if it must.
--account--session-id
$ kdev downkdev restoreFinish or repeat the restore on the running box, or add what an older version has. Never a rollback.
--from vN--from-backup
$ kdev restore --from v12kdev workspace filesExactly what a saved version holds: what the next kdev up would restore.
--version vN--json
$ kdev workspace files --version v12kdev historynext releaseRecent saved sessions: who ran them, how they ended, how many files, restore state.
-n N--json
$ kdev history -n 5kdev backupAn exact copy of the running box on this machine, kept in ~/.config/kdev/workspace.
$ kdev backupkdev accountEvery signed-in account with its GPU and TPU hours left this week.
--json
$ kdev accountkdev account usePick the account that runs, and pays for, the next box.
$ kdev account use bobkdev account addSign an account in through the browser; run it again to refresh a token.
$ kdev account add bobkdev workspaceThe shared notebook: owner, sharing, members and saved versions.
$ kdev workspacekdev workspace createMake the group notebook and share it as Can Edit. The owner runs this once.
--group
$ kdev workspace create --group my-teamkdev workspace joinUse the group notebook someone already shared with you.
$ kdev workspace joinkdev setupGet this machine ready. Does only what is missing, so it is safe to run again.
$ kdev setupkdev tunnel setupCreate the Cloudflare tunnel and its DNS record in your zone, once.
$ kdev tunnel setupkdev config setChange a setting: gpu, hours, git-remote, ssh-alias and the rest. kdev config lists them.
KEY VALUE
$ kdev config set gpu t4kdev doctorCheck every dependency, account token, the workspace and the tunnel DNS. Exits 1 if something is broken.
--fix
$ kdev doctor --fixNothing matches. Try files, port or account, or read the full reference.
Exit codes: 0 ok · 1 failed, with the command that fixes it · 2 usage · 130 cancelled. Add -v to any command to log each Kaggle API call. Full reference →
kdev is a thin layer over Kaggle and Cloudflare. It does nothing to hide what it does, and it is not a way around anyone's rules.
Security and limits, in full →Password login is off. The box accepts the keys saved in the workspace; delete a line to revoke a machine.
Kaggle has no API for notebook Secrets, so tunnel credentials sit in the private notebook. Anyone with Can Edit can read them.
12 hours per GPU session, 9 on TPU, a weekly quota per account, 20 GB of /kaggle/working saved per version.
Kaggle allows one account per person and restricts tunnelling out of notebooks. Accounts have been banned for both. kdev hides nothing.
Still unsure? Ask in Discussions.
Install kdev (uv tool install kdev-cli), run kdev setup once, then kdev up. kdev submits your notebook with a small cell on top that starts an SSH server and a Cloudflare tunnel, then writes a host called kaggle into ~/.ssh/config. After that, ssh kaggle gives you a root shell on the Kaggle machine.
Yes. Once kdev up reports ready, open VS Code, choose Remote-SSH and connect to the host kaggle. Extensions, the terminal and the debugger run on the Kaggle box with its GPUs, CUDA and Python environment.
Kaggle saves /kaggle/working as the output of every Save & Run All session, however it ends. kdev finds the version you left off at and restores it into the next box before you connect, including the symlinks, empty folders and executable bits Kaggle drops, so a virtualenv keeps working.
Whatever Kaggle gives the account: CPU, two NVIDIA T4s, a P100 or a TPU, and L4, A100 or H100 where an account has them. A T4 box we measured had 2 × 15 GB of VRAM, 31 GB of RAM, 4 vCPUs, Python 3.12, CUDA 12.8 and over 900 preinstalled Python packages. Each account gets 30 GPU-hours and 20 TPU-hours a week; sessions last up to 12 hours, 9 on TPU.
Every account in a Kaggle group can run the same shared notebook, each on its own weekly quota. When the active account runs short, kdev up shows every account’s remaining hours and asks which one should run the box. Only real, distinct people’s accounts should be used: Kaggle allows one account per person.
No. Without a domain kdev uses a Cloudflare quick tunnel with a new hostname each session, and kdev up finds it for you. With a domain on Cloudflare’s free plan, kdev tunnel setup creates a named tunnel once and the hostname never changes.
kdev is free and open source under the MIT licence. It is an independent project for research and education, not affiliated with or endorsed by Kaggle, Google or Cloudflare. Kaggle restricts tunnelling out of notebooks; read its terms before you use kdev.
Nothing ends. The box keeps running on Kaggle until its time is up. Run kdev up again from any machine or account in the group and it connects to the running box instead of starting a second one.
About seven thousand lines of Python with an offline test suite against a fake Kaggle. You can read the whole thing in an afternoon. For anything bigger than a fix, open an issue first and say what you want to change and why.
src/kdev
cli.pyentry point, one error boundarycommands/parse, call logic, render with uisession · persistence · quotathe behaviour, testable without a terminalapi · auth · tunnel · sshcfgthe edgeskdev_box.pystandard library only; runs on the box✓ A bug fix comes with a test that fails without it
✓ Tests stay offline: the fake Kaggle in test_cli.py
✓ Conventional Commits, the why in the body
✓ Everything the user sees goes through ui.py
# once per machine
$ kdev setup
# start the box, or connect to the running one
$ kdev up
# or VS Code → Remote-SSH → kaggle
$ ssh kaggle
# optional: stop early and hand the quota back
$ kdev down