Aquanode LogoAquanode Docs

Command Reference

Every aq command: auth, deploy & connect, save/share/fork, pod lifecycle, idle policy, and jobs.

This page covers every aq command. If you just want the fastest path to a running box, start with the Quickstart instead, come back here for the rest of the surface.

All commands

CommandWhat it does
gpusBrowse live GPU prices across every provider (no account needed)
loginPair this CLI to your Aquanode account (device login)
upRent the cheapest matching GPU and bring up a working pod
deployRestore a save onto a freshly-rented Aquanode GPU box
importBring a box you rent elsewhere in as an Aquanode pod
sshOpen a shell on a pod (managed key + ~/.ssh/config alias)
pushSend your working directory to a box you already rented
runPush the working directory, then run a command on the box
logsRead a detached run's output
lsList your machines: what is running and what it costs
statusShow a pod's status, HTTPS URL, and credentials
saveSave a pod's current state into its named lineage
shareGet a link to one saved version of a pod
forkTurn a share link into a new pod in your own library
edit-versionEdit a saved version's label, description, or visibility
pauseSave a pod, then release its machine (resume later with up)
autopauseTurn a pod's auto-pause on or off
force-detachBreak a pod's lease even mid-sync (can lose unsynced work)
sync-nowForce a pod's sync tick right now
podsList the pods you own
idleView or change a deployment's auto-pause thresholds
jobCreate, run, follow and cancel GPU jobs
downTear down a pod (stop the rented GPU box)
logoutRemove the stored CLI credential
whoamiShow the current login state
versionPrint the aq version
helpShow the built-in help

Every command also accepts -h/--help for its own flag list.

Marketplace

gpus

aq gpus [flags]

Bare, aq gpus prints a market-summary table - one row per GPU model, cheapest per-GPU rate first, with how many providers and offers back it - so you can see at a glance which model is cheapest and how contested it is. This is the one aq command that needs no account, no API key, and no aq login - it just reads the same public marketplace endpoint.

$ aq gpus
GPU               VRAM   FROM $/GPU-HR  CHEAPEST AT   REGION        PROVIDERS  OFFERS
RTX3070           8      0.0500         simplepod     CA            2          12
A16               2GB    0.0590         vultr         New Jersey    1          19
V100              16     0.0700         simplepod     US            3          46
...
H100              80GB   2.5250         hyperstack    CANADA-1      4          60
H200              141GB  3.6200         massecompute  us-east-1     3          38
B200              -      6.0600         hyperstack    CANADA-1      2          9
B300              288GB  7.8900         runpod        EU-NL-1       1          12
585 offers across 41 GPU models. `aq gpus --gpu <model>` lists every offer, `--limit 0` the whole feed
ready to rent one? `aq login` pairs an account, then `aq up --gpu <model>` deploys.

Any flag - a filter, --limit, or --json - switches it to the per-offer table instead, listing every individual offer that matches:

FlagMeaning
--gpu <model>Filter to a GPU model (substring, case-insensitive, e.g. "B200")
--provider <name>Restrict to a single provider (e.g. runpod)
--region <name>Filter to a region (substring, case-insensitive)
--max-price <n>Only show offers at or below this per-GPU hourly rate ($/GPU-HR)
--limit <n>Max rows to print, 0 for all (default 20; --json prints every match unless you set this explicitly)
--jsonPrint the filtered offers as JSON instead of a table
$ aq gpus --gpu H100 --limit 5
GPU   GPUS  VRAM  PROVIDER      REGION        AVAIL  $/GPU-HR  $/HR TOTAL
H100  1     80GB  massecompute  us-central-3  1      2.4500    2.4500
H100  2     80GB  massecompute  us-central-3  2      2.4500    4.9000
H100  1     80GB  hyperstack    CANADA-1      1      2.5250    2.5250
H100  1     80GB  hyperstack    CANADA-1      1      2.5250    2.5250
H100  1     94GB  runpod        unknown       1      2.5900    2.5900
showing 5 of 77 offers; use --limit 0 for all
ready to rent one? `aq login` pairs an account, then `aq up --gpu <model>` deploys.

Compare on $/GPU-HR, not $/HR TOTAL

The underlying feed's raw price is a whole-offer total for every provider except Akash, which already reports a flat per-GPU rate - see the Marketplace API docs for the full breakdown. aq gpus normalizes all of that for you into $/GPU-HR, so that column is always an apples-to-apples per-GPU rate no matter which provider or GPU count an offer has. $/HR TOTAL is just $/GPU-HR times GPUS, shown so you can see what the whole box costs.

--json emits the raw offer fields from the marketplace feed plus a derived pricePerGpuHour, so scripts can sort or filter without re-deriving the per-GPU math themselves.

Authentication

login

aq login

Device-pairing flow: prints a URL and a confirmation code, optionally opens your browser to it, and waits for you to approve the pairing in the console. See the Quickstart for a full example.

logout

aq logout

Removes the stored CLI credential from your machine.

whoami

aq whoami

Shows the current login state.

version

aq version

Prints the installed aq version.

help

aq help

Shows the built-in command list.

Deploy & connect

up

aq up [flags]

Rents the cheapest matching GPU and provisions the box: bare by default, or with an app installed via --comfyui/--jupyter. See Quickstart for a walkthrough.

FlagMeaning
--gpu <model>Filter to a GPU model (substring, e.g. "RTX 4090")
--gpus <n>How many GPUs the box should have (default 1, max 8)
--max-price <n>Only rent GPUs at or below this hourly price
--provider <name>Restrict to a single provider (e.g. massecompute)
--name <name>Set the deployment's display name (default: auto-generated)
--show-secretsEcho the service password to stdout (hidden by default)
--auto-pauseEnable auto-pause on this deployment (off by default)
--warn-after <duration>With --auto-pause: warn after this much idle time
--pause-after <duration>With --auto-pause: auto-pause after this much idle time
--comfyuiInstall ComfyUI
--jupyterInstall Torch + Jupyter

Bare by default

Pick neither --comfyui nor --jupyter and aq up gives you a plain GPU box with no app installed - just SSH access. Add --comfyui or --jupyter to bring one up on it.

deploy

aq deploy --snapshot <id> [flags]

Rents a fresh GPU and restores a save onto it, moving an environment to a different (or cheaper) box, optionally on a different provider than the one it came from.

FlagMeaning
--snapshot <id>The save to deploy (an id from aq or the console, e.g. ext-42)
--gpu <model>Filter to a GPU model (substring, e.g. "RTX 4090")
--gpus <n>How many GPUs the box should have (default 1, max 8)
--max-price <n>Only rent GPUs at or below this hourly price
--provider <name>Restrict to a single provider (e.g. massecompute)
--name <name>Set the deployment's display name (default: auto-generated)
--show-secretsEcho the service password to stdout (hidden by default)
--comfyuiRelaunch ComfyUI on the restored data
--jupyterRelaunch Torch + Jupyter on the restored data instead
--no-appRestore only, do not relaunch an app

--comfyui is the default if you pass neither app flag; pass --no-app for a restore with no app relaunched.

import

aq import [flags]
aq import --resume <pod-id>

Run this ON a GPU box you rent somewhere else. It surveys the box, shows you exactly what it will and will not capture, and (once you agree) captures the environment into a new Aquanode pod you can launch on any provider we support. See aq import for the full walkthrough.

FlagMeaning
--dry-runSurvey and print the plan; capture nothing, upload nothing
--include <path>Add a path to the capture set (repeatable)
--exclude <path>Drop a detected path from the capture set (repeatable)
--name <name>Name the resulting pod (default: derived from the hostname)
--yesSkip the confirmation prompt
--resume <id>Continue an interrupted import into the pod it already created
--launchAfter importing, rent a box and restore onto it (billable)
--gpu <model>With --launch: GPU model to rent (default: the one observed)
--max-price <n>With --launch: only rent at or below this hourly price
--provider <name>With --launch: restrict to a single provider

The survey prints three groups: what is being captured, what is being skipped (with sizes, so you can add it with --include), and what could not be read at all. The third group matters most: a directory listed there is not in the capture, and the usual fix is to re-run under sudo. Directories below a size floor are not listed individually; the survey says so when it applies one.

A non-interactive shell without --yes refuses rather than guessing. Package manifests (dpkg/rpm/pip) are recorded for reference and are never replayed on restore.

ssh

aq ssh                     # your only live deployment
aq ssh <name|id>           # a deployment by --name or id
aq ssh <name> -- <cmd>    # run a command instead of opening a shell
FlagMeaning
--printPrint the ssh command that would run, and exit
-L <spec>Forward a local port, e.g. 8888:localhost:8888 (repeatable)
--user <name>Override the login user (default: root)

aq manages ~/.ssh/aquanode.config (included from your ~/.ssh/config) with one aq-<name> alias per live box, so ssh, scp, rsync, and VSCode Remote-SSH all work with that alias with no aq involved. If you have no SSH key at all, aq generates a passphrase-less one at ~/.ssh/aquanode_ed25519. See the Quickstart for more examples.

push

aq push [name|id] [flags]

Sends your working directory to a box you already rented, over the same managed ssh alias aq ssh uses. It is a plain directory copy, not a new protocol, so anything you could do with scp/rsync by hand keeps working alongside it.

FlagMeaning
--from <dir>Local directory to send (default: the current directory)
--to <dir>Destination directory on the box (default: /workspace)
--exclude <pattern>Skip paths matching this pattern (repeatable)
--no-default-excludesDo not skip .git, node_modules, __pycache__, and friends
--deleteDelete remote files that no longer exist locally (needs rsync)
--printPrint the transfer command that would run, and exit

run

aq run [name|id] [flags] -- <command...>

Pushes the working directory, then runs a command on the box with the terminal attached. It is aq push followed by aq ssh -- cd <dir> && <cmd>, folded into one command.

FlagMeaning
--from <dir>Local directory to send (default: the current directory)
--to <dir>Destination directory on the box (default: /workspace)
--dir <dir>Directory to run in on the box (default: the push destination)
--exclude <pattern>Skip paths matching this pattern (repeatable)
--no-default-excludesDo not skip .git, node_modules, __pycache__, and friends
--deleteDelete remote files that no longer exist locally (needs rsync)
--no-pushRun without sending the working directory first
--detachStart the command and return; it keeps running after you disconnect
--printPrint the commands that would run, and exit

With --detach, aq run prints a run id to stdout and returns immediately. Read its output with aq logs.

logs

aq logs [name|id] [flags]

Reads a detached run's output (the other half of aq run --detach). Defaults to the most recent run on the box.

FlagMeaning
--run <id>Read a specific run id (default: the most recent)
--dir <dir>Working directory the run was launched in (default: /workspace)
-n <lines>How many trailing lines to show (default 200)
-fKeep streaming as the run writes more
--listList this box's runs and their status instead of printing a log
--printPrint the ssh command that would run, and exit

ls

aq ls [--all]

Lists your machines: what is running right now and what it costs (id, name, status, GPU, provider, hourly rate, age). Live boxes only by default; pass --all to include closed and failed ones too. This is different from aq pods, which lists what you own whether or not it is currently running a box.

FlagMeaning
--allInclude closed and failed deployments, not just live

status

aq status <name|id>

Re-checks a provisioning or running pod: state, HTTPS URL, and credentials (add --show-secrets to print the password).

down

aq down <name|id> [--save]

Tears the pod down and stops billing. --save saves first; termination is skipped if the save fails.

Save, share & fork

Renamed from aq snapshot

This used to be aq snapshot. The verb is now aq save, there is no aq snapshot command or alias.

save

aq save <name|id> [--name <lineage>] [--path <dir>]

Saves the pod's current state into its named save lineage. The first save on a pod asks for a lineage name once (Enter accepts the default, which is the pod's own name; a non-interactive shell just uses the default). Every later save reuses that lineage silently and increments its version (v1, v2, v3, ...).

share

aq share <name|id> <ver>

Prints a link to one immutable saved version, e.g. aq share comfyui 3. The link always points at that exact version, never at whatever the lineage's head becomes later.

fork

aq fork <token|link> [--name <name>]

Turns a link from aq share (someone else's, or your own team's share of a team you've since left) into a brand new pod in your own library. Registers ownership only; it does not itself boot any hardware. --name defaults to a name derived from the source.

edit-version

aq edit-version <name|id> <ver> [--label <text>] [--description <text>] [--visibility private|team|public]

Edits a saved version's label, description, and/or visibility. Only the flags you pass change; there is currently no way to clear a label/description back to empty.

Pod lifecycle

pause

aq pause <name|id>

Saves the pod, then releases its machine. aq up takes no pod argument and always starts a fresh, empty box, so it is not how you pick this back up. Restore it with aq deploy --snapshot <id>, where <id> is the paused deployment's numeric id (find it with aq ls --all or the console).

autopause

aq autopause <name|id> on|off

Turns this pod's auto-pause on or off, using the platform's default idle thresholds. This is not the same as idle: idle policy is a per-deployment threshold config that always outranks this, and autopause carries no thresholds of its own. Use aq idle set to change when idle counts as idle, and autopause to turn pausing on pods on/off at all.

force-detach

aq force-detach <name|id> --yes

Breaks the pod's lease even mid-sync, for when a deployment died holding it and it needs freeing before anything else can attach. --yes acknowledges work since the last completed sync may be lost; there is no silent form of this command.

sync-now

aq sync-now <name|id>

Forces a sync tick right now instead of waiting for the pod's own schedule, e.g. right before aq share/aq fork so the link reflects your latest work. Requires the pod to be attached to a running deployment.

pods

aq pods

Lists the pods you own: name, whether it's running, latest saved version, and size.

Idle policy

idle

A per-deployment auto-pause policy (warn/stop thresholds, GPU idle %). It always outranks a pod's own aq autopause preference above.

aq idle status <name|id>   # show the policy and its current live verdict
                            # (ACTIVE / IDLE / UNKNOWN)
aq idle set <name|id>       # update the policy (only the flags you pass change)
FlagMeaning
--warn-after <duration>Warn after this much idle time, e.g. 30m, 1h
--pause-after <duration>Auto-pause after this much idle time, e.g. 1h
--gpu-threshold <percent>GPU utilization below which the box counts idle
--on / --offEnable / disable auto-pause

See also Pause and resume for how this behaves across the console and API.

Jobs

job

Everything about jobs is a subcommand of aq job. It is a group rather than top-level verbs because aq run already means "push this directory to a box and run a command on it" and aq logs already tails a box, and aq run mybox and aq run myjob are the same string.

aq job create <pod> <version> --max-instances <n> [--name <name>] [--on <alias>]
aq job point <name> <version>
aq job rm <name>
aq job run <job> [--input file] [--wait [--wait-seconds <n>]]
aq job runs <job>
aq job logs <job> <run-id> [-f] [--attempt <n>]
aq job cancel <job> <run-id>

create makes a pod version runnable as a job. --max-instances is required: a job hands out a GPU budget, so it never defaults to unbounded. --name defaults to the pod's own name. --on <alias> pins the job to a box you already attached, which Aquanode never rented and does not bill.

point repoints a job at a different version in its lineage: also how you roll back. rm removes the job; the pod and its versions are untouched.

job run

FlagMeaning
--input <file>Path to a JSON file of the declared params (default: no inputs)
--waitWait for the run to complete (up to --wait-seconds, default 30)
--wait-seconds <n>Maximum seconds to wait for completion (only with --wait, capped at 120)

job runs

Lists a job's recent runs: id, status, phase, and reason. "unservable" means Aquanode could not get the run a machine at all — it does not mean your own code failed.

job logs

FlagMeaning
-f, --followKeep printing as the run writes more
--attempt <n>Read one attempt's log (default: the latest)

A run that moved between machines has several attempts. The default is the latest rather than all of them concatenated, which would put the timestamps out of order in the middle with nothing marking the seam.

If the machine cannot be reached, aq says so on stderr rather than printing nothing — an empty log and an unreadable one are different facts.

job cancel

Stops a run. Billing stops when the machine is released.

Environment variables

VariableMeaning
AQ_API_URLAquanode API base (default https://server.aquanode.io/api/v1)
AQ_CONSOLE_URLAquanode console base aq share links point at (default https://console.aquanode.io)
AQ_CONFIG_DIRCredential directory (default <user-config-dir>/aq)
AQ_SSH_KEYPrivate key to use for box access (default: your ~/.ssh key, else aq's managed ~/.ssh/aquanode_ed25519)
AQ_NO_BROWSERSet to skip auto-opening the approval URL