lium up
Create a new pod.
lium up [NODE_ID] [OPTIONS]
Arguments
NODE_ID— Node UUID, HUID, or index from the lastlium ls. Optional: when you omit it, the filter flags below narrow the list and the best node is picked automatically, with no menu — the only prompt is the confirmation before renting, which--yesskips.
Options
Selection & naming
| Flag | Effect |
|---|---|
--name, -n NAME | Custom pod name (auto-generated if not specified) |
--template_id, -t ID | Specify template ID directly (skips template prompt) |
--gpu TYPE | Filter nodes by GPU type (e.g. H200, A6000) |
--count, -c NUM | Filter by number of GPUs per pod |
--country CODE | Filter nodes by ISO country code (US, FR, …) |
--min-cpus N | Only nodes that report at least N CPU threads (the CPUs column of lium ls) (since 0.0.40) |
--ports, -p NUM | Only consider nodes with at least NUM available ports, and request NUM ports on the pod |
--yes, -y | Skip confirmation prompt |
--no-ssh | Create the pod and return to the shell; no SSH session is opened |
By default a successful lium up ends by opening an interactive SSH session to
the new pod (in --image mode it streams the container logs instead). Pass
--no-ssh when you want the command to return — in a script, or when you plan
to connect later with lium ssh.
Verification
The GPU-count check and both flags shipped in lium 0.0.34. Since 0.0.35 a rent without --count is checked against the node's free GPUs (0.0.34 compared it with the host's total, which failed a correct pod on a partly rented split node). Since 0.0.39 (lium#209) a lium up --gpu <type> rent on a backend that offers rent_by_spec (lium.io does) asks the server for one GPU unless you pass --count, and the check uses the count the server rented; the free-GPU rule stays for lium up <node>. 0.0.33 reports success as soon as the pod is RUNNING with an SSH command, so on that version a silent downgrade (fewer GPUs billed than requested) or phantom GPUs (billed for more than the container exposes) is only visible from inside the pod.
Once the pod is ready — and after any --ttl/--until schedule is set — up compares the GPU count the API bills the pod for with the count you asked for: --count; without it, the node's free GPUs for lium up <node>, or (since 0.0.39) the count the server rented for lium up --gpu <type>, one GPU. When the /pods row carries no GPU count for the pod, that comparison is skipped and up reports success; pass --verify-gpus if you need the count proven — it then checks what nvidia-smi sees against the count you asked for. A mismatch prints GPU count mismatch: requested N, pod is billed for M (node <id>), leaves the pod running (remove it with 'lium rm <pod>') and exits 1 with the code gpu_count_mismatch. The two flags go further:
| Flag | Effect |
|---|---|
--verify-gpus | Also count the GPUs nvidia-smi -L sees over SSH inside the pod and compare with the billed count; a mismatch exits 1 with both numbers (pod is billed for 8, nvidia-smi reports 4). The connection is retried for about 90 s while sshd comes up; when it never answers in that window, or the command itself fails (nvidia-smi missing, driver not loaded), the pod is kept and up exits 1 with gpu_verification_failed (since 0.0.34) |
--strict-gpus | Remove the pod automatically on a mismatch of either check, so a scripted lium up … && python train.py never pays for a pod that is not what was asked for; a pod that could not be checked over SSH is kept (since 0.0.34) |
Auto-termination
| Flag | Effect |
|---|---|
--ttl DURATION | Auto-terminate this long after the rent (e.g. 6h, 45m, 2d) |
--until WHEN | Auto-terminate at local time (today 23:00, tomorrow 01:00, 2026-05-08 15:30) |
The schedule is set the moment the rent returns a pod id, before up waits for the pod to become ready (since 0.0.42; earlier versions set it only once the pod was RUNNING). So it holds when the wait runs out (--timeout, --ready-timeout) or the pod never starts: the exit message names the removal time (Auto-termination is scheduled for 2026-09-10 08:40 UTC (in 2.0h): the pod is removed then even if it never becomes ready), and lium schedules lists it while the pod is still PENDING. If the schedule call itself fails right after the rent, up says so, waits, and tries once more when the pod is ready; the pod is kept either way. When that wait then runs out too, the pod has no end time — the exit message says Auto-termination (--ttl/--until) was NOT scheduled and points at lium rm <pod> --in <duration> to set one.
Use lium schedules to view and cancel an existing schedule.
Waiting
Everything in this section shipped in lium 0.0.35 (lium#214). On 0.0.33 and 0.0.34 lium up polls every 10 s with no time limit and prints nothing until the pod is ready.
| Flag | Effect |
|---|---|
--timeout SECONDS | Time budget for the whole command — finding the node, renting it and waiting for the pod (default 900). When it runs out before the rent, up exits 1 with no pod created (a --volume new: volume is kept); when it runs out while the pod is still starting, up exits 1 and names the pod, which keeps running and billing; remove it with lium rm if you do not want it (since 0.0.35) |
--ready-timeout SECONDS | Bound only the wait for the pod to become ready: exit 1 with the pod named, pod left running. Default: whatever --timeout leaves (so up to 900 s). A pod that reaches FAILED/STOPPED or disappears fails immediately, exit 3 (pod_start_failed), with its last recorded status, whatever the timeout (since 0.0.35) |
While it waits, up prints a line when the pod's status or phase changes, and at least every 30 s — waiting for <pod>… <STATUS> (<n> s), followed by the backend's estimate when it sends one: waiting for eager-owl-7c… PENDING (12 s) · est. ready in ~18 s (phase: pulling image). The lines appear on a terminal and behind a pipe alike, so a scripted caller can see whether the pod is in PENDING, pulling its image or already RUNNING. A pod that reaches a terminal state (TERMINAL_POD_STATUSES: FAILED, STOPPED, ERROR, TERMINATED, DELETED, REMOVED, CANCELLED, CREATION_FAILED, BROKEN, REBOOT_FAILED, DELETING) or disappears fails immediately — exit 3, pod_start_failed — with the cause the backend recorded (for example Container creation failed … (failure_step: ssh_connect)). --ready-timeout caps only the wait for readiness; --timeout caps everything.
How often it looks (since 0.0.35): up checks the pod list every 2 s for the first 90 s of the wait and every 10 s after that — 0.0.34 checked every 10 s throughout — so a pod the backend marks RUNNING at ~22 s is reported within 2 s. A pod that does not appear in the list at all is reported as missing 20 s after the first check, whatever the cadence, and also when the --timeout budget ends at that same moment.
Container
| Flag | Effect |
|---|---|
--image IMAGE | Docker image to run (e.g. pytorch/pytorch:2.0, nvidia/cuda:12.0, or name@sha256:<digest> to pin one exact build) |
--dockerfile PATH | Build the pod image from a local Dockerfile (custom build). Mutually exclusive with --image and --template_id. |
--internal-ports LIST | Internal ports to expose (comma-separated, e.g. 22,8000,8080) |
-e, --env KEY=VAL | Environment variable; can be repeated |
--entrypoint CMD | Override container entrypoint |
--cmd CMD | Override container command |
--jupyter | Install Jupyter Notebook (auto-selects an available port) |
--ssh-name NAME | Name for a freshly registered SSH key (default: cli-<user>@<hostname>) |
Custom Dockerfile builds (--dockerfile): the image is built on the node from your Dockerfile — no build context is uploaded, so the Dockerfile must be self-contained: the Dockerfile is the only file the build sees. COPY or ADD of files next to it (COPY app.py /app/, ADD ./data /data) would fail there with not found (COPY --from=<stage> and heredoc COPY <<EOF need no local files and work). A check in lium up that refuses such a Dockerfile before renting and lists the lines is not released yet; lium 0.13.4 and earlier rent the pod and the build then fails. Fetch those files in a RUN step (git clone, pip install), or build and push the image yourself and run it with --image. The build runs in an isolated container with public internet access (cloud metadata and private network ranges are blocked), and ADD <url> / ADD ${var} directives are rejected. Keep the file under 64 KiB. The pod is SSH-accessible once the build finishes, just like a template-based pod. The --env, --entrypoint, --cmd, and --internal-ports flags don't apply here — define those in the Dockerfile itself.
If the build fails, the cause that lium up prints (and the executor-rent.failed entry in GET /pods/{id}/events) ends with Build output (last lines): followed by the last 25 non-empty lines the build printed, cut to 2000 characters. A line that carries a credential — a token=, secret=, password= or key= assignment such as ARG HF_TOKEN=…, an ENV or ARG with such a name and a value (ENV API_KEY value), or a URL with a user (https://TOKEN@…, https://user:password@…) — is replaced by [line redacted: it contains a credential]. That redaction is by pattern, not a guarantee: a token printed on its own line stays visible to everyone who can read the pod's events, so keep secrets out of the Dockerfile and out of anything it prints. An older validator reports only the failing step, for example (failure_step: docker_build).
Volumes
| Flag | Effect |
|---|---|
--volume, -v SPEC | Volume spec — see below |
--volume-encryption / --no-volume-encryption | Encrypt the local volume where the node supports it. Enabled by default. |
Volume spec forms:
id:<HUID>— attach an existing volume by HUIDnew:name=<NAME>[,desc=<DESC>]— create and attach a new volume
Restore from a backup
| Flag | Effect |
|---|---|
--restore-backup BACKUP_ID | Completed backup to restore after the pod starts |
--restore-to PATH | New or empty directory below the pod's local volume mount |
The two restore flags must be used together. The pod becomes running and accessible before restoration finishes. Do not modify the restore directory until lium bk restore-logs reports completion.
Examples
# Basic
lium up # Auto-picks the best node, asks to confirm
lium up cosmic-hawk-f2 # Specific node by HUID
lium up 1 # Node #1 from last ls
lium up --name dev-pod # Custom name
# Filtering nodes
lium up --gpu H200
lium up --gpu A6000 -c 2
lium up --gpu H200 --country FR
lium up --ports 5
# Verify the GPU count inside the pod too (exit 1 on mismatch; --strict-gpus also removes the pod) — since 0.0.34
lium up --gpu H200 --count 8 --verify-gpus --yes
lium up --gpu H200 --count 8 --verify-gpus --strict-gpus --yes
# Auto-terminate
lium up --gpu H200 --ttl 6h # Stop after 6h
lium up --gpu H200 --until "tomorrow 09:00" # Stop tomorrow morning
# Container customization
lium up 1 --image pytorch/pytorch:2.0
lium up 1 --image my-image -e API_KEY=xyz -e DEBUG=1
lium up 1 --internal-ports 22,8000,8080
lium up 1 --jupyter # Spin up with Jupyter
# Custom Dockerfile build (image built remotely from your Dockerfile)
lium up --gpu A6000 --dockerfile ./Dockerfile
lium up 1 --dockerfile ./Dockerfile --name my-build
# Volumes
lium up 1 --volume id:brave-fox-3a
lium up 1 --volume new:name=my-data,desc="Training data"
# Create a pod and restore a backup after it starts
lium up 1 --restore-backup 8fbb30f6 --restore-to /root/restored
# Bound the whole command (exit 1 and name the pod if it is still starting after 5 min) — since 0.0.35
lium up --gpu RTX5090 --yes --no-ssh --timeout 300
# Direct template + skip prompt
lium up 1 --template_id abc123
lium up --gpu H200 --yes
See also
lium ls— find a node firstlium templates— pick a templatelium volumes— pre-create a volumelium schedules— manage--ttl/--untilschedules