Working in Colab — Drive Files, GPU Details, the CLI, and Web UIs

Mount Google Drive for persistence, inspect GPUs and compute units, manage runtimes from the terminal with the Colab CLI, and reach web UIs like ComfyUI through proxies and tunnels.

September 24, 2026
google-colabgoogle-drivegpucolab-clicloudflare-tunnel

Four skills cover most day-to-day Colab work: keeping files alive with Google Drive, knowing what hardware you were assigned, driving runtimes from a terminal, and reaching web applications that run on the runtime. This guide covers all four as they play out in practice.

Google Drive files

The runtime's disk is temporary; Drive is yours. Mounting Drive inside a notebook gives the runtime read-write access to a folder, so anything you save there survives the runtime.

Mount it in a cell:

from google.colab import drive
drive.mount("/content/drive")

A browser prompt asks you to authorize access. The mount appears at /content/drive/MyDrive. After that it is ordinary file work — bring a dataset in, process it on the fast local disk, and copy results back:

import os, shutil

# Work on runtime disk (fast), not directly on the mount
os.makedirs("/content/work", exist_ok=True)
shutil.copy("/content/drive/MyDrive/data/dataset.csv", "/content/work/dataset.csv")
# ... process /content/work/dataset.csv, write /content/work/results.csv ...
os.makedirs("/content/drive/MyDrive/results", exist_ok=True)
shutil.copy("/content/work/results.csv", "/content/drive/MyDrive/results/results.csv")

The example assumes a data/dataset.csv folder in your Drive; adjust the paths to match your own layout.

Three habits make this reliable:

  • Do the work on local disk. Reading and writing many small files directly on the mount is slow and can trigger I/O errors. The FAQ recommends copying archives (.zip, .tar.gz) to the runtime and unpacking there instead of touching thousands of small files through the mount.
  • Keep Drive's root small. More than roughly ten thousand items in My Drive can break mounting entirely. Use subfolders.
  • Treat the mount as a sync target, not scratch space. If a copy is interrupted mid-write, data in transit can be lost — write locally, then copy the finished file.

The persistence rule is simple: anything you care about gets written to the Drive mount before the runtime dies. Files left in /content do not come back.

GPUs and compute units

Find out what you got

The runtime picker shows choices, not assignments. Once connected, ask the machine:

!nvidia-smi

On a GPU runtime this prints the GPU model, its VRAM, and current usage:

+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 580.82.07              Driver Version: 580.82.07      CUDA Version: 13.0     |
|=========================================+========================+======================|
|   0  NVIDIA RTX PRO 6000 Blac...    Off |   00000000:05:00.0 Off |                    0 |
| N/A   31C    P0             48W /  600W |       0MiB /  97887MiB |      0%      Default |
+-----------------------------------------------------------------------------------------+

Two numbers matter most:

  • VRAM (the 97887MiB total above) is GPU memory. Models and their activations must fit here.
  • System RAM is separate, and much larger on high-RAM shapes. Loaders offload weights there when the model is too big for VRAM.

Disk is a third budget entirely. Check it before large downloads:

!df -h /

Track usage and spend

The Resources panel (Connect dropdown → View resources) shows your compute unit balance and burn rate. GPUs draw units faster than CPUs; larger GPUs draw faster still. Release hardware the moment a job finishes — Disconnect and delete runtime frees the machine, and the FAQ's own advice is to close tabs and avoid GPUs you are not using.

Compute units are a budget, not a reservation. Google does not publish per-GPU burn rates, and hardware availability changes with demand — treat any fixed "hours per GPU" figure you see (including ours elsewhere on this site) as an observation, not a promise.

Check CUDA compatibility before installing anything

Some newer GPUs require newer PyTorch builds. Before a big install, confirm the toolchain matches the machine:

import torch
print("torch", torch.__version__, "| cuda", torch.version.cuda)
print("gpu:", torch.cuda.get_device_name(0))
print("arch:", torch.cuda.get_arch_list())

If the GPU's architecture is missing from arch (for example, sm_100 on Blackwell GPUs), upgrade torch from the cu128 index and restart the runtime before anything else. Fixing this after installing a stack of dependencies is a common wasted afternoon.

The Colab CLI

Google's Colab CLI manages runtimes from a terminal (Linux and macOS only). It is the difference between a notebook you drive by hand and a machine you can script.

uv tool install google-colab-cli   # or: pip install google-colab-cli

A session's lifecycle:

colab new -s work --gpu L4          # allocate a runtime
colab status -s work                # show hardware and shape
colab console -s work               # raw shell on the VM (tmux)
colab upload -s work ./data.csv /content/data.csv
colab download -s work /content/output.png ./output.png
colab stop -s work                  # release the VM

Useful commands beyond the basics:

CommandPurpose
colab run --gpu L4 script.pyProvision a fresh VM, run a local script, tear the VM down
colab url -s work --openOpen the session in the browser notebook
colab drivemount -s workMount Drive without writing the notebook cell
colab usageCompute-unit balance and burn rate from the terminal
colab install -s work torchInstall packages on the VM via uv

The one limitation that will bite you

colab sessions lists every runtime active on the backend — but some show a [?] marker instead of a name. That marker means the runtime is untracked in your local CLI state: colab console and colab url both fail with "Session not found", because the CLI has no local record to attach through. Two things cause it:

  • The runtime was created in the browser, so the CLI never had a record.
  • The runtime was created with the CLI, but its connection token expired (they last about an hour) and the CLI pruned its local entry while the VM kept running — a known issue (#147) that leaves orphaned assignments if you respond by creating new sessions.

The workable workflow: create each session with the CLI (colab new), work without multi-hour gaps between commands, and release it with colab stop when done. If you see [?] entries, check Runtime → Manage sessions in the browser and disconnect runtimes you no longer need — orphaned VMs otherwise sit there consuming resources until Colab reclaims them.

Accessing web UIs from the runtime

Anything that runs a web server on the runtime — ComfyUI, Gradio, JupyterLab — needs a way to reach your browser. Start the server, confirm it locally, then choose an access path.

Start a server the way the app's docs recommend, on 0.0.0.0:

nohup python main.py --listen 0.0.0.0 --port 8188 --enable-cors-header '*' \
  > /content/app.log 2>&1 &

Confirm it answers before debugging any access path:

curl -I http://127.0.0.1:8188/

Colab's built-in proxy (try this first)

from google.colab.output import eval_js
print(eval_js("google.colab.kernel.proxyPort(8188)"))

This prints a googleusercontent.com URL that renders the app inside Colab. It avoids tunnels entirely and is the fastest path in our testing.

Cloudflare quick tunnel

For a standalone URL:

!wget -q -O /tmp/cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
!dpkg -i /tmp/cloudflared.deb
!cloudflared tunnel --url http://127.0.0.1:8188 --no-autoupdate &

The tunnel prints a trycloudflare.com URL. Two failure modes we hit running ComfyUI through one:

  • Slow first load can be the tunnel, not the app. In our run the quick tunnel stalled on the first burst of frontend assets — the page sat on its loading screen for minutes while the server responded instantly locally. If your symptoms match, waiting or using the built-in proxy is a better first move than switching software.
  • Blank UI with 403s points at CORS. When an app is served through an iframe or tunnel and refuses its own JavaScript assets, the page renders empty. For ComfyUI, the --enable-cors-header '*' server flag fixed it.

ngrok is the other common option; we considered it during a slow load but the page arrived first, so we cannot say whether it would have been faster.

Diagnosis order

When the page will not load, work inward: (1) does curl on 127.0.0.1 answer? If not, the server is down — check its log. (2) Does the built-in proxy load? If yes, the app is fine and the tunnel is the problem. (3) Only then change tunnels. Reinstalling models does not fix a network path, and restarting a healthy server does not speed up a slow one.

Where to go next