CLI reference
The matmul command rents GPUs from your terminal: find an offer, launch a VM or Docker image, SSH in, and watch your balance. It's a thin wrapper over the Python SDK, which calls the REST API.
Install and log in
pip install matmul-cloud matmul --help matmul login
matmul login prints a one-time code and opens the console in your browser. Sign in if you need to, check that the page shows the same code, and click Authorize this CLI. The CLI then receives a new API key named after your machine (for example cli: robin-mbp) and saves it to ~/.config/matmul/config.json (mode 600). Over SSH, or on a machine without a browser, it prints the link instead: open it on any device. The key acts as you, in the organization you're signed in to. (Browser login needs a matmul-cloud release after 0.1.0; with 0.1.0, use an API key as below.)
Only approve a code you just started yourself. If someone sends you a login link, click Deny: approving it would give their terminal access to your account.
| Command / flag | Meaning |
|---|---|
matmul login | Log in through the browser and save a new key. |
--name NAME | Name the key cli: NAME instead of cli: <hostname>. |
--no-browser | Don't open a browser; print the link and code. |
--url URL | API base URL. Defaults to https://api.matmul.cloud; saved with the key when it's another URL. |
--api-key KEY | Save an existing key instead of logging in through the browser (--key works too). |
matmul logout | Revoke the saved key on the server and remove it from this machine. |
matmul logout --keep-key | Only remove it from this machine. |
For CI and scripts, where nobody can click Authorize, create a key on the CLI & API page of the console and set MATMUL_API_KEY, or save it with matmul login --api-key lmk_.... Every command reads these environment variables, which take precedence over the file:
| Variable | Meaning |
|---|---|
MATMUL_API_KEY | API key to use. |
MATMUL_API_URL | API base URL. |
MATMUL_CONFIG | Path of the config file to read and write instead of the default. |
Wherever a command takes an instance, you can give its id (ins_...) or its name. A name has to be unambiguous among your instances that aren't deleted.
Offers
matmul offers
Lists machines you can launch right now, cheapest first, with GPU, VRAM per GPU, vCPUs, RAM, region, price per hour and offer id.
| Flag | Meaning |
|---|---|
--gpu TYPE | GPU model, e.g. H100, A100, L40S. |
--count N | GPUs per machine. |
--region REGION | One region, as shown in the REGION column. |
--max-price USD | Only offers at or under this $/hr. |
--kind gpu|cpu | Only GPU machines, or only CPU-only machines. Leave it out for both. (needs a matmul-cloud release after 0.1.0.) |
SSH keys
| Command | What it does |
|---|---|
matmul ssh-key add [--name NAME] [--file PATH] | Registers a public key. Without --file it uses ~/.ssh/id_ed25519.pub, then id_ecdsa.pub, then id_rsa.pub. --name defaults to your $USER. |
matmul ssh-key ls | Lists your keys: id, name, fingerprint. |
matmul ssh-key rm ID | Removes a key. |
An organization can hold up to 20 keys. Viewers can list keys but not add or remove them.
Instances
matmul instance create
matmul instance create --name dev --gpu H100 --max-price 3 --wait matmul instance create --name nb --gpu H100 --image pytorch/pytorch:latest --keep-alive --wait
--gpu takes the cheapest match. To launch one particular machine from the list (a region, a size, a price), pass its id from the OFFER ID column of matmul offers with --offer, and its price as the guard:
matmul offers --gpu H100 # note the OFFER ID and PRICE matmul instance create --name dev --offer <OFFER_ID> --max-price <PRICE> --wait
Offers are live. If that machine has been taken since you listed it, the launch fails with "that offer is no longer available; search again"; if its price went above --max-price, it fails with "the price rose above your max_hourly_price_cents; search again". Nothing is charged either way: run matmul offers again. The console's Launch page shows the same command, filled in, for any offer you pick.
| Flag | Meaning |
|---|---|
--name NAME | Required. Lowercase letters, digits and dashes, starting with a letter, up to 32 characters. |
--gpu TYPE | Launch the cheapest offer for this GPU. Needed unless you pass --offer. |
--count N | GPUs per machine (default 1). |
--region REGION | Only consider offers in this region. |
--offer ID | An exact offer id from matmul offers, instead of --gpu. |
--max-price USD | Price ceiling in $/hr, as a number (2.59). The launch is refused if the live price is above it. (matmul-cloud 0.1.0 can read some prices a cent low; if a launch at the listed price is refused, add a cent. Fixed in the next release.) |
--ssh-key ID | Which key to install. Optional when you have exactly one. |
--image IMAGE | Docker image to run on the VM. Leave it out for the plain VM (Ubuntu with the NVIDIA driver, no container; no CUDA toolkit). |
--keep-alive | Keep an interactive image running (runs sleep infinity). Can't be combined with --args. |
--args ARGS | Arguments passed to the container: a single line, up to 1024 characters. |
--env KEY=VALUE | Container environment variable. Repeatable, up to 20. |
--port PORT | Publish a container port on the machine. Repeatable, up to 10; not 22. |
--shm GB | Shared memory for the container, 0 to 256 GB. |
--expose PORT | Give a port a public HTTPS link. Repeatable. Not switched on yet. |
--wait | Wait until the instance is running, then print the SSH command. |
--args, --keep-alive, --env, --port and --shm need --image. With --wait, the CLI shows elapsed time and status while the provider boots the machine, which often takes several minutes, and gives up after 15 minutes. With --image, the instance is running only once the container is up, so pulling a large image adds to the wait.
matmul instance ls / get / rm
| Command | What it does |
|---|---|
matmul instance ls | Lists your organization's instances: id, name, status, GPU, image, region, price, running time, cost so far and how to connect. |
matmul instance get REF | Shows one instance. |
matmul instance rm REF | Deletes the instance. Billing stops right away and its slot is free for a new launch; the disk is gone. |
Instance status is one of provisioning, running, error, deleting and deleted. ls and get print a warning first if your account is frozen.
matmul ssh
matmul ssh [--host] REF [-- COMMAND...] matmul ssh dev -- nvidia-smi matmul ssh dev -- 'nvidia-smi; df -h' # one quoted string: a shell command line matmul ssh dev -- python -c 'print(1)' # several words: passed on exactly as typed
Opens a shell on a running instance, using your system ssh. On an instance with an image you land inside the container; --host gives you the VM instead. Anything after -- runs instead of a shell: a single argument is run as a shell command line, the way plain ssh does it, and several arguments are passed on word by word. When input isn't a terminal (a script, CI, or a pipe such as echo 'print(1)' | matmul ssh dev -- python), the command runs without asking for one, inside the container too.
In matmul-cloud 0.1.0, put --host before the instance name, and container commands always ask for a terminal and treat a single quoted argument as one word. --host after the name, command lines and non-terminal use needs a matmul-cloud release after 0.1.0.
Public app links: expose, unexpose, ports
matmul expose REF PORT, matmul unexpose REF PORT and matmul ports REF manage public HTTPS links to ports on an instance. They're built but switched off for now; the CLI says so if you try. Until then, use SSH port forwarding: ssh -L 8888:localhost:8888 ....
Billing
| Command | What it does |
|---|---|
matmul billing balance | Prepaid balance, new-account limits if they apply, and a warning with the grace time left if the account is frozen. |
matmul billing ledger [--limit N] | Recent credits and charges (default 20). |
matmul billing add-credit --usd AMOUNT | Prints a Stripe checkout link. Open it and pay in your browser. |
Billing commands need the owner role. The API enforces the top-up minimum ($10) and maximum; see Pricing & billing.
Managed jobs
Not available on MatMul yet. The commands exist, and when the server has jobs switched off, matmul run says so and suggests matmul instance create. How they'll work is in Managed jobs.
| Command | What it does |
|---|---|
matmul run [flags] -- COMMAND | Launches a job that runs COMMAND on a GPU machine. |
matmul ls | Lists your jobs. |
matmul status NAME | Shows a job (by name, the most recent with it, or by job_... id). |
matmul logs NAME | Prints a job's logs. |
matmul down NAME | Stops a job and releases its machine. |
Flags for matmul run:
| Flag | Meaning |
|---|---|
--name NAME | Job name (default job- plus 6 hex characters). Up to 16 characters: lowercase letters, digits, dashes. |
--gpu TYPE | GPU type, e.g. H100. |
--gpus-per-node N | GPUs per machine (default 1; needs --gpu). |
--gpus TYPE:COUNT | Older spelling of --gpu plus --gpus-per-node. |
--max-price USD | Refuse to launch if the whole job (all nodes) costs more than this $/hr. |
--nodes N | Machines (default 1, up to 8). |
--cpus N | vCPUs, e.g. 4 or 4+. |
--memory GB | Memory in GB, e.g. 16+. |
--disk GB | Disk size, 10 to 2048 GB. |
--setup CMD | Command run once before the job. |
--env KEY=VALUE | Environment variable. Repeatable, up to 50. |
--wait | Wait for the job to finish, print its logs, and exit 0 if it succeeded, 1 if not. |
Exit codes and errors
Errors go to stderr as error: ... with the API's message. The exit code is 2 for authentication and permission errors (a bad key, or your role doesn't allow it) and 1 for anything else.
- "no API key: set MATMUL_API_KEY or run `matmul login`": log in first.
- "invalid api key": the key was revoked or mistyped. Run
matmul loginagain, or create a new key. - "the code expired before it was approved" or "the login was denied in the browser" (from
matmul login, exit code 1): runmatmul loginagain. A code is good for 10 minutes. - "not allowed for your role": viewers can't launch or add and remove SSH keys; only owners can use billing.
- "insufficient balance" or "account frozen": add credit with
matmul billing add-credit. - "that offer is no longer available" or "the price rose above your max_hourly_price_cents": run
matmul offersagain. - "instance limit reached": delete an instance first; its slot frees up as soon as you do. New accounts can run one at a time.
- "GPU capacity is temporarily limited; please try again later": MatMul is at its platform-wide capacity cap. Nothing was launched or charged; try again later (see Pricing & billing).
The old LEMNOS_* environment variables and ~/.config/lemnos/config.json still work if the MATMUL_* ones aren't set.