Changelog
0.1.50
GPU jobs retry a not-ready host instead of failing
When a GPU machine's NVLink fabric hasn't finished initializing, a job can crash at startup with CUDA error 802 ("system not yet initialized") before your code runs. anycloud now treats this as a problem with the machine rather than a fault in your container, and retries the job on a fresh machine — which almost always clears it. It most often shows up on multi-GPU machines such as H100 pairs.
Lambda deployments reach newer regions and fall back across instance types
Lambda GPU deployments can now use regions that Lambda offers but that weren't
yet in anycloud's catalog (for example us-southeast-1) — anycloud now reads
Lambda's own catalog directly instead of a slower third-party snapshot, so newly
available regions show up within hours. A GPU request such as H100:1 also falls
back across equivalent instance types automatically, so a deployment lands on
whichever is available instead of failing on the cheaper one.
Lazy image loading now uses eStargz
Large-image lazy loading now uses eStargz instead of SOCI v2. Publish your image
in eStargz format — one docker buildx flag, or a nerdctl image convert, with
no separate index artifact to manage — and anycloud starts it lazily where the
runtime supports it, running the container while its layers are fetched on
demand. anycloud status still marks the running event [lazy-loaded] or
[full pull]; small or ordinary images pull as before.
0.1.49
Large images start sooner with SOCI v2
Large GPU and machine-learning images can spend most of their launch time just
downloading. If your image is pushed to GHCR in SOCI v2 format, anycloud can
start it lazily where the runtime supports it: the container runs while its
layers are fetched on demand, so it doesn't wait for the whole image to download
first.
anycloud status marks the running event [lazy-loaded] when this happens, or
[full pull] otherwise. Small or ordinary images pull as before.
Azure bucket sync data now avoids temporary VM storage
Azure VM-host deployments now place host-side input, output, and checkpoint
bucket directories under /var/lib/anycloud/deployments on the managed OS disk
instead of Azure's temporary /mnt resource disk, so bucket data survives VM
deallocation during in-place spot recovery. Other providers keep the existing
/mnt layout. The host paths are stored per VM so already-running deployments
keep their original bucket directories after an API upgrade.
Region-pinned deployments retry capacity sooner
When a cloud reports insufficient capacity for an explicitly pinned region,
anycloud schedules another launch attempt after about one minute instead of
waiting behind the shared ten-minute capacity observation. Unpinned deployments
keep the longer observation window so they can fail over without repeatedly
probing an exhausted target, and regional and account quota protections remain
unchanged. While waiting, anycloud status confirms that an automatic capacity
retry is scheduled.
Lambda launch retries clean up duplicate instances
Lambda deployments now tag launched instances and sweep stale same-deployment instances around launch retries. This prevents duplicate or orphaned Lambda instances when the provider accepts a launch request but the client only sees a transient failure.
Workload image baking has been removed
Jobs and servers now always boot from a provider base VM and pull the resolved
Docker image. The CLI and Python SDK no longer expose workload-image baking,
cache reuse, or image warm-up controls, and status no longer includes a baking
lifecycle phase. The entire anycloud baked command group, including its list,
copy, and prune operations, has also been removed. Earlier changelog entries
below describe the behavior of those historical releases.
Existing baked workload AMIs and their snapshots are not automatically discovered or deleted by this release. They remain in the owning cloud account until an account owner removes them with provider-native tooling; generic AnyCloud base/runtime images must be retained.
0.1.48
Preempted spot deployments no longer stay falsely running
If the API restarted while a cloud provider was bringing a preempted VM back
online, the deployment could remain recorded as running even though its only
VM was already recorded as preempted. Those stale deployments then appeared in
anycloud list and anycloud terminate indefinitely. Recovery is now committed
before waiting on the cloud restart, interrupted attempts resume through the
normal recovery queue, and upgraded API servers automatically repair existing
running deployments whose live VM records are all preempted.
Failing bucket syncs back off between retries
When a continuous output or checkpoint sync failed (expired storage token, revoked bucket access, network trouble), it retried immediately in a tight loop instead of waiting for the normal sync interval — hammering the storage API and burning VM CPU next to the workload until the problem cleared. Failed attempts now wait the same interval as successful ones. Applies to deployments launched after this release; already-running VMs keep the sync script they launched with.
Bucket sync health now comes from rclone's own errors
anycloud status derived bucket-sync health by keyword-matching service
logs, so a harmless systemd warning could make a healthy output sync render
as failed — both live and in a past deployment's event history. Sync health
is now read from the rclone log itself and only rclone's explicit errors
count as sync failures; the harmless warning is also stripped when showing
older deployments' history.
Clearer terminal status for jobs with output buckets
Terminal events now show the final output sync result separately from the
workload's own exit code (e.g. errored [exit: 137] [final sync: succeeded, attempt: 1]), a stopped sync service now shows as stopped instead of
disappearing from status entirely, and sync diagnostics are no longer
duplicated into termination events.
0.1.47
anycloud update actually restarts the local API server again
Since 0.1.46, anycloud update silently failed to restart a running local
API container onto the new version: it printed the target version and
exited as if it had succeeded, but the container was left on its old image.
anycloud update now restarts it correctly. If a local API server has been
stuck on an old version, run anycloud update again after upgrading.
Cross-cloud input buckets no longer get stuck in syncing
Deployments with a cross-cloud input bucket (e.g. compute on one provider,
an S3 input bucket on another) could get stuck retrying in syncing
indefinitely. The pre-sync connectivity check now verifies read access for
input buckets instead of attempting a write, matching the read-only
credentials those buckets are already granted.
0.1.46
Bake-hit boots wait for the warm-up, and it targets the right files
On a cache-hit boot from a baked image, the container now waits (up to 60 seconds) for the boot-time page-cache warm-up to finish before starting, so the workload's first reads land warm instead of racing an in-progress warm-up. The warm-up itself also skips large files a running container never actually reads — copies and caches left over from pulling and building the image, along with libraries the image ships but doesn't use at runtime — so its limited time budget goes to the files that matter. Re-bake existing images to pick up both changes.
0.1.45
Faster initialization on baked-image boots
VM initialization now confirms Docker readiness through the init system's native ready signal instead of repeatedly querying the daemon, reaches new VMs with a connection-level probe before attempting SSH logins, and the boot-time warm-up reads the container runtime's bookkeeping first. Together these decouple initialization from the background warm-up: multi-minute initialization on large baked images drops to under a minute. The readiness and connection improvements apply to all deployments immediately; re-bake to pick up the warm-up ordering change.
0.1.44
Boot-stable warm-up for large baked images
The boot-time warm-up introduced in 0.1.42 now reads boot-critical files
first and large image data last, reducing contention with VM startup.
For large images, pair --bake with --disk-tier high: baked-image boots
are fastest there and model loads start warm. On the default disk tier,
booting very large baked images can still delay or retry provisioning —
prefer a normal pull (--no-bake-cache) or the high tier for those.
Re-bake existing images to pick up the new warm-up ordering.
Target selection
When the interactive submit and serve VM picker can't fetch quota limits in
time, it now says so and shows the full catalog, instead of silently dropping
the quota-aware ranking. Quota lookups are also cached longer, so repeat picks
and anycloud quota status checks return faster.
0.1.43
Baked-image warm-up now covers GPU base images
The boot-time warm-up introduced in 0.1.42 read only Docker's classic storage directory. GPU base images store cached layers through Docker's containerd image store, which keeps its data in a separate location — so GPU-family bake hits warmed almost nothing and still started cold. The warm-up now reads both storage locations. Re-bake existing images to pick up the fix; the bake e2e suite now also verifies that the warm-up did proportional work on a live bake-hit VM.
0.1.42
Faster container starts on baked-image cache hits
VMs booted from a baked image now read the cached Docker image into memory in the background at boot, restoring the warm state a fresh Docker pull leaves behind. Large images (model weights, CUDA libraries) previously paid cold-disk reads on first access, which could make a cache-hit start slower than a fresh pull. Applies to images baked from this version onward; older baked images start cold until re-baked.
AWS disk tiers
anycloud submit, anycloud serve, cloud config, and the Python SDK now support
an AWS diskTier / --disk-tier option for choosing gp3 root-volume
performance independently from root disk capacity. The initial tiers are
medium, high, and ultra.
On baked-image cache hits, high and ultra also request the fastest supported
EBS volume initialization rate for the root volume. Workloads that still start
faster with a normal Docker pull should use --no-bake-cache; disk tiers are a
root-disk performance knob, not a guarantee that prebaked AMIs beat registry
pulls.
gp3 root volumes by default
AWS deployments now always launch with a gp3 root volume. Previously, deployments that did not set a disk size or disk tier could fall back to the base image's gp2 default, which is slower — especially at small disk sizes — and 25% more expensive per GB.
Baked-image cache opt-out
anycloud submit, anycloud serve, anycloud serve upgrade, and the Python
SDK now support a no-bake-cache option for runs that should force a normal base
VM boot and Docker pull even when a matching baked image exists. It can be
combined with legacy --bake to pull normally and refresh the baked image after
the pull.
Release hardening
Unit test runtime was reduced for status and Azure gateway coverage, keeping the release validation path faster without reducing behavioral checks.
0.1.40
AWS baked-image startup reliability
AWS bake-hit launches now request a bounded EBS volume initialization rate for the root volume, reducing unpredictable snapshot lazy-load latency when booting from prebaked AMIs. If AWS rejects that optimization because of regional quota or capacity pressure, provisioning retries without it instead of failing the deployment.
The AWS serve-bake integration test now verifies that bake-hit VMs launch from the baked image and request the bounded initialization rate while the instance is still live.
Local Kubernetes release hardening
The local Kubernetes provider contract now uses a Never pull policy for the
locally built SSH sidecar image after importing it into k3d, preventing CI from
falling back to Docker Hub for a test-only image tag.
0.1.39
Bake reliability
Explicit bake now flushes Docker filesystem state before snapshotting and records whether bake failures happened during flush or image creation. Failed bakes no longer fall through into workload execution, and same-tag baked images with different digests are kept until an explicit prune removes them.
Quota and status
anycloud quota status now prompts for spot or on-demand quota in interactive
mode and supports explicit --spot / --on-demand filters while keeping JSON
output script-friendly. Quota integration coverage now checks AWS and Azure
provider parity against cloud API data.
Status telemetry is now throttled per user and deployment so watch and wait polling loops do not flood analytics.
Updates and release hardening
anycloud upgrade is now an alias for anycloud update, with clearer output
when the CLI is current and there is no local API server to restart.
Homebrew-managed installs now update through Homebrew from anycloud update;
when Homebrew is already on its latest formula, the command still restarts a
stale local API server to match the installed CLI.
Nightly bake e2e jobs have longer timeout headroom and stricter phase checks, so release-adjacent bake regressions surface before publishing.
0.1.38
Quota and status internals
Quota resource resolution now uses shared AWS and Azure resolvers, improving quota lookup consistency across provider gateways, API handlers, and the CLI.
Internal provider status domains now use enums across API and CLI paths, keeping status handling consistent as quota and deployment flows evolve.
0.1.37
Local Docker-control
AnyCloud can now run Local workloads through a Docker-control container on the API host, using the same workload path as VM deployments.
anycloud logs works for Local deployments, streaming through the API without
exposing SSH material. Local missing-GPU failures now stop instead of retrying
the same fixed host.
Serve upgrades
anycloud serve upgrade <id> <image> [command...] replaces a running serve
deployment while preserving its existing https://<id>.anycloud.sh URL.
Target selection
The interactive submit and serve VM picker now shows quota-aware ranking and spot pricing while keeping region selection unpinned.
Image inspection now filters CUDA/ROCm-incompatible GPU fallback targets and rejects images whose compressed layers cannot fit on the selected disk.
Baked images and registries
Private GHCR manifest inspection now reports real auth failures for --bake
instead of falling back to misleading digest errors.
anycloud baked list has shorter age formatting, more stable picker columns,
and safer regional caching that avoids reusing partial scans.
Local API reliability
The CLI now discovers local API containers on non-default host ports.
anycloud update checks /v1/version, verifies the target API image before
stopping the old container, and can recover a failed restart on the next update.
Operational hardening
Catalog refresh falls back to usable cache when available. Lambda serve rotates away from regions without required firewall rulesets. Container startup health now catches unhealthy, restarting, and missing-GPU states before publishing endpoints.
0.1.36
Choose which API server the CLI talks to
The CLI now remembers a preferred API server, so you don't need to set API_URL
on every command.
anycloud api use <url>saves a hosted API as the active server (stored in~/.anycloud/api-url). Pass a deployment ID to pick one of your hosted APIs,localto return tohttp://localhost:8080, or run it with no argument for an interactive picker of healthy, compatible servers.anycloud api listshows your local and hosted API servers with their health, version, and which one is active.--jsonemits the same data for scripting.anycloud api infoshows the active server, where the setting came from, and whether its version matches your CLI.anycloud api serve --usemakes a newly created hosted API active once it's healthy.
API_URL still works as a one-command override and takes precedence over the
saved setting.
CLI and API versions must match
The CLI and the API server it talks to must now be the same version. If they
differ, commands fail fast with a clear message — run anycloud update for a
local API, or anycloud api list then anycloud api use <target> to switch to a
matching server.
anycloud logs for VM-host deployments
anycloud logs [id] prints workload container stdout/stderr logs for VM-host
deployments, and anycloud logs [id] --watch streams them. Provider-run-image
deployments such as Vast are reported as unsupported for now.
anycloud list distinguishes jobs and servers
anycloud list now includes a TYPE column and a type-aware summary, so mixed
job/server history is easier to scan. Use anycloud list --type job or
anycloud list --type server to filter. --json includes deploymentType, and
--csv keeps the existing columns in order while appending deploymentType as
the final column.
Credential prompts are more consistent
Commands that need saved credentials now share the same resolver behavior: one eligible credential is selected automatically, multiple eligible credentials open the same autocomplete picker on a TTY, and non-interactive runs fail with a message naming the flag to pass.
Bare interactive anycloud submit, anycloud serve, and anycloud api serve
now prompt for saved credentials before opening the compute target picker, then
pin the selected credential on the deployment. Bucket commands can also omit
--credentials in interactive flows and still send the resolved credential name
to the bucket API.
anycloud baked list uses the same credential selection behavior. Its default
table now includes a Cloud column, while both --by-region and --json remain
available.
0.1.35
anycloud baked manages baked VM images
A new anycloud baked command group manages the prebaked VM images that --bake
creates:
anycloud baked listshows the baked images discovered in a selected named credential/account, grouped by the container image they were baked from.anycloud baked copy(AWS) copies a baked image to other regions so deployments there boot warm without re-baking. Copies are idempotent, and--waitblocks until each copy is ready.anycloud baked pruneremoves baked images you no longer need from a selected named credential/account, with--unused-forto keep recently-used ones and--region,--image, and--digestfilters to scope the sweep. This replacesanycloud images prune.
anycloud list filters by credential
anycloud list --provider <cloud> has been removed. Use
anycloud list --credential <name> to narrow deployment history to a specific
saved credential. The filter matches both deployments pinned to that credential
and unpinned deployments whose VMs were later provisioned with it.
Quota commands require an explicit credential
anycloud quota request and anycloud quota status now operate against one
named credential at a time. Interactive runs still pick or auto-select a matching
credential, but scripted runs should pass --credential <name> so quota reads
and requests cannot accidentally scan the wrong cloud account.
anycloud status --verbose shows VM diagnostics
anycloud status --verbose now includes container exit details, container logs,
and bucket-sync diagnostics when a VM health check finds a problem. The default
status view stays concise and points you to --verbose when logs are available.
Read-only status checks also no longer append noisy same-state deployment events
or API log errors just because a user inspected a deployment.
Clearer GPU runtime handling
AnyCloud now resolves the runtime a GPU VM needs as CUDA, ROCm, or unsupported.
NVIDIA CUDA VM-host targets still default Docker GPU access to --gpus all, but
AMD/ROCm and other unsupported accelerator targets now fail clearly instead of
silently booting a CUDA base image. The GPU docs were updated to match the
automatic GPU access behavior.
Hosted API owner checks run before lookups
Hosted API requests now enforce the owner policy before named credential, secret, catalog, or image lookups. Denied callers receive the authorization failure without being able to probe saved server state first.
0.1.34
Local API Docker access is opt-in
anycloud api start binds the API port to 127.0.0.1 and mounts the host Docker
socket only when explicitly started with --enable-local-docker. To run
anycloud submit --local, restart the local API with
anycloud api start --enable-local-docker; that opt-in is preserved by
anycloud update.
anycloud ssh restored
anycloud ssh <id> is available again for VM-host jobs and servers. It opens an
interactive shell in the workload container by default, with --vm for host VM
diagnostics and --snapshot for exited-container inspection. SSH keys are not
returned from status; the CLI requests explicit, audited SSH access from the
API when the command runs.
Configurable anycloud serve listen port
Server deployments still default to PORT=8088, but you can now override it with
--env PORT=<port> (CLI) or env={"PORT": "<port>"} (Python SDK). The public URL
and HTTPS routing are unchanged.
anycloud serve always runs servers on-demand
Server deployments (anycloud serve and anycloud api serve) no longer ask you
to choose between on-demand and spot pricing when you pick a spot-capable VM
type — they always run on-demand, so picking a target is one fewer prompt.
Passing --spot to a server deployment is now rejected with a clear error
instead of being applied.
Interactive target picker shows disk sizes
When you pick a compute target interactively for anycloud submit or
anycloud serve, each option now lists the instance's local disk size alongside
its vCPU, memory, and price. The picker aligns every option into stable columns,
so machine type, compute, CPU, memory, disk, and rate line up down the list and
are easier to scan and compare.
anycloud status shows spot and disk size
anycloud status now lists the spot setting and disk size as their own rows in a
deployment's summary. Previously a spot deployment was only hinted at by a small
marker next to the VM type, and the disk size was not shown at all — so you can
now confirm both choices without digging through your deploy configuration.
anycloud status shows why an image pull failed
When a VM-side Docker image pull fails, anycloud status now surfaces the
underlying Docker daemon output — for example manifest unknown, or an
authentication or disk-space error — in a "Docker output" block beneath the
concise failure line, instead of a bare "Failed to pull image". This applies to
both remote-VM and direct pulls, and to failures recorded earlier, so you can
tell why a pull failed without digging into the VM.
--bake accepts single-arch and digest-pinned amd64 images
anycloud submit --bake and anycloud serve --bake now work with more kinds of
images. Previously --bake could only resolve a linux/amd64 digest from a
multi-arch image; it now also handles plain single-manifest linux/amd64 images
and images referenced by digest (image@sha256:...), inspecting the image's
config to confirm it really targets linux/amd64 before baking. When an image
genuinely has no linux/amd64 build, the rejection message is now clearer about
what to do.
anycloud exec captures complete output more reliably
anycloud exec no longer drops trailing standard error: it waits for all
buffered error output to flush before finishing, so the last lines of a failing
command's diagnostics are reported instead of being cut off, and a slow output
consumer no longer leaves the stream hanging. The Python SDK's Job.exec() now
keeps streamed output as raw bytes and decodes it once at the end, so multibyte
characters (emoji, accented or non-Latin text) that land on a chunk boundary are
no longer corrupted.
Faster failures and cleaner failover for GPU and Lambda serve
A GPU deployment whose container image needs a newer driver than the host
provides now fails fast with the underlying driver-mismatch message, instead of
silently retrying the same doomed target until the launch budget runs out. On
Lambda, hitting your account instance limit is now reported as a quota issue (so
the CLI points you at anycloud quota) rather than rotating through regions that
can't help, and tearing down a Lambda server that failed over across regions now
removes the firewall rules it created in every region, not just the last one.
0.1.33
anycloud serve on Lambda
Server deployments can now run on Lambda, alongside AWS, GCP, and Azure, with the
same public https://<id>.anycloud.sh URL and HTTPS routing as the other
providers.
anycloud serve --bake
Server deployments can now opt into baked VM images. Serve uses the same server-resolved image digest as jobs, so a baked image created by a job can be reused by a server, and a baked image created by a server can be reused by a job when the image digest, cloud account, region, and base image family match.
Hosted API restricted to its owner
A hosted AnyCloud API (anycloud api serve) now serves only the account that
deployed it and rejects requests from anyone else, instead of being reachable by
any caller who has the URL.
0.1.32
anycloud api serve deploys a hosted AnyCloud API
Runs the AnyCloud API as a long-running server on your own cloud compute instead
of locally, printing the public URL and API_URL once it's healthy (--no-wait
to skip the wait). anycloud api start now refuses to start when a database
exists without its key, instead of generating a mismatched one.
Python SDK get_or_submit() for restart-safe workflows
A restarted workflow step reattaches to the deployment it already submitted instead of duplicating it, using a stable ID derived from the workflow id, step name, and submission spec.
anycloud quota status shows new requests immediately
A request you just made with anycloud quota request now appears right away with
its state, instead of disappearing until the provider's own history catches up.
anycloud serve origins locked to Cloudflare
Server HTTP ports are now firewalled to Cloudflare's edge ranges instead of open to the whole internet; existing servers are tightened on their next firewall reconcile.
anycloud serve deployments on Azure are reachable again
anycloud serve runs on any supported provider. On Azure specifically, some HTTP
requests to a server's https://<id>.anycloud.sh URL could be dropped before
reaching it, so the deployment looked unreachable even when healthy — now fixed
for both IPv4 and IPv6.
GCP skips regions that can't see the requested machine type
Unpinned GCP deployments drop candidate regions where the requested machine type isn't visible before provisioning, so they fail over to a working region faster.
Azure terminations clean up leftover network resources more reliably
If an Azure termination fails partway through, the deployment's network interface and public IP are now marked for cleanup up front, so the next cleanup pass reclaims them rather than leaving them behind in your subscription.
0.1.31
CLI installs now use public release assets and Homebrew
The anycloud CLI now ships as platform tarballs in the public
anycloud-sh/releases repo instead
of through npm. The installer downloads the matching tarball and verifies it
against checksums.txt before installing.
macOS and Linuxbrew users can install with
brew install anycloud-sh/tap/anycloud and upgrade with
brew upgrade anycloud-sh/tap/anycloud. anycloud update now checks GitHub
Releases for newer versions and points Homebrew-managed installs back to
Homebrew instead of overwriting them.
anycloud quota request GPU picker starts empty
The interactive anycloud quota request GPU picker no longer preselects curated
GPU instance types. Curated options still appear first, but users now explicitly
choose every GPU VM type they want to request.
anycloud status can watch a deployment until it finishes
anycloud status <id> --watch now polls and redraws the status view until the
deployment reaches a terminal state. Use --interval <seconds> to adjust the
poll cadence. For scripts, anycloud status <id> --watch --json emits one
compact status object per line.
0.1.30
anycloud list gets a time window and a result limit; -a/--all is removed
anycloud list now shows your most recent deployments by default, newest
first, instead of only the last 24 hours — so a bare anycloud list no longer
comes up empty when your latest work is a few days old. Two new flags adjust
the view, on both list and the status picker:
-p, --period <window>— only deployments started within a window, e.g.anycloud list -p 7dor-p 24h.-n, --limit <count>— how many to show, newest first.
The -a, --all flag has been removed. To reach older deployments, widen the
window with -p or raise the count with -n. Every list query is now bounded,
so listing stays responsive on accounts with long histories.
The --status, --provider, and -f/--filter filters now search your full
history rather than only the page being shown, so filtering for an older
deployment no longer comes up empty when it falls outside the recent window.
anycloud cost --period all is removed
anycloud cost no longer accepts --period all. Cost is always computed over a
recent window of deployments rather than your entire history, so "all-time" was
misleading. Pass an explicit window instead — e.g. anycloud cost --period 90d
(the default is still 30d).
Azure bucket sync no longer loses storage access after cleanup
On Azure, deployments in a subscription share a single identity that grants their VMs read/write access to bucket storage. Routine cleanup of orphaned resources could mistakenly remove that shared access, after which bucket sync failed with permission errors on every running and new deployment until the API was restarted. Cleanup now preserves the shared access grant, and each deployment restores it automatically if it is ever missing — so bucket sync recovers on its own.
Invalid cloud credentials are flagged instead of failing on every deployment
When a saved cloud credential starts failing authentication — for example after
its secret is rotated or expires — anycloud now marks it invalid instead of
retrying the same failing call on every deployment and cleanup pass. New work
that would use it is skipped, and cleanup for affected deployments pauses (so it
stops re-hitting the provider and flooding logs) until the credential is fixed.
anycloud credentials list shows which credential is failing and since when, and
with notifications enabled anycloud sends a one-time alert so a broken credential
surfaces instead of failing silently. Re-entering a valid secret clears the flag;
affected deployments can then be resubmitted.
0.1.29
anycloud list stays responsive on accounts with long histories
The list and cost commands now select the deployments to display first, then total their VM usage, cost, and latest status only for those — instead of aggregating across every deployment an account has ever created and trimming afterward. Accounts with thousands of past deployments no longer pay whole-history cost on each list. Results are unchanged except that deployments sharing an exact start time now sort in a stable order.
Cleanup fails fast on broken cloud credentials
When a cloud credential is rotated, expired, or missing required permissions, resource teardown now gives up immediately instead of retrying the same failing delete for several minutes, and Azure requests that would otherwise hang now time out. This clears stuck cleanup work sooner; a genuinely broken credential still needs to be corrected before its leftover resources can be removed.
API containers use vanilla Node memory defaults again
The API Docker image no longer starts through a shell entrypoint that auto-sizes
V8 heap memory from the host or container memory limit. Local API containers now
use Node.js's default memory behavior unless operators explicitly provide
NODE_OPTIONS.
0.1.28
Large queued batches no longer overwhelm the API server
Before dispatching a queued deployment, the server checks cloud quota and availability across candidate regions. Each queued deployment used to run that check independently, so a deep queue of similar jobs could issue thousands of simultaneous cloud API calls every few seconds — enough to starve the server and slow every command. Identical checks are now shared: a batch of similar deployments performs one sweep together, and a failed sweep logs a single warning instead of flooding the logs. Region filtering behavior is unchanged.
0.1.27
Releases now ship as one forward-only public line
The release flow no longer has separate latest and stable channels. Each
release publishes the matching API image before publishing public CLI assets,
then publishes the Python SDK and agent skill from the same version-bump commit.
This prevents an updated CLI from pointing at an API image that has not been
published yet.
anycloud update now moves forward to the current public release and restarts a
running local API server automatically. Version arguments, channel selectors,
and --no-restart have been removed so CLI/API installs stay in lockstep.
Local API databases also record the newest app version that touched them, and
older API containers refuse to start against newer forward-migrated data.
0.1.26
More history reads are bounded to live work or explicit windows
The local API now adds indexes for the other recurring database reads that can grow with deployment history: live VM checks, spend windows, pending cost reconciliation, active-state monitors, and daily digest ranges. Retry and startup-recovery monitors now start from the small set of active deployments and probe their events, rather than grouping all historical events.
These changes keep full history in SQLite; they make the common reads pay for the live fleet or the requested time window instead of the lifetime size of the database. Slow SQLite queries are also logged, rate-limited, so future unbounded reads show up in API logs before they become outages.
0.1.25
The local API server restarts itself after crashes and reboots
anycloud api start now runs the server with Docker's unless-stopped restart
policy: if the process crashes or the machine reboots, the API comes back on
its own instead of staying down until someone notices — while jobs run
unsupervised, a dead API means completed VMs keep billing. An explicit
anycloud api stop still keeps it stopped.
Crashes also stay diagnosable now: the server's recent logs are saved to
~/.anycloud/api-last.log before the container is replaced or removed (they
were previously destroyed with it), container logs rotate instead of growing
without bound, and anycloud api status shows a restart count when the server
has been crashing.
Deployment listings no longer include secrets
The deployment list API response included each deployment's decrypted SSH
private key, environment variables, and GitHub token — none of which
anycloud list ever displayed. Listings are now redacted. Flows that
genuinely need the key, like anycloud exec, are unaffected: they fetch it
through the single-deployment status endpoint.
The API server stays responsive with a large deployment history
A background check that runs every minute used to scan the server's entire
deployment history; once that history reached hundreds of thousands of records
(large, long-running fleets) it could stall the server for seconds at a time,
slowing every command. The scan is now indexed — about 60× faster on a real
customer database — so anycloud list and anycloud status stay snappy
during big runs.
The API server uses your machine's memory instead of a fixed ~4GB cap
The server previously ran with Node.js's default heap ceiling (~4GB) no matter how much memory the machine had, which could crash it under heavy fleet load even on large machines. It now sizes its heap to 75% of available memory.
anycloud status separates billable time from wall-clock duration, and shows cost
The status header used to show a single Duration measured from submission to completion — including time spent queued or retrying before any VM existed. It now also shows Billable, the time VMs actually existed (summed across spot replacements) — the time your cloud charges you for — and a Cost row with the deployment's spend and hourly rate, marked "(est.)" while it's estimated from catalog prices rather than reconciled against your cloud bill. All three update live for running deployments.
0.1.24
Fixed: image validation no longer depends on local Docker
anycloud submit used to verify your image with a local Docker pull, which could
wrongly reject a valid image on Apple Silicon Macs (a "no matching manifest for
linux/arm64/v8" error) and depended on tools not present on a default macOS
install. Image validation now happens server-side, so it behaves the same from
the CLI, the Python SDK, and CI, and no longer needs Docker on your machine.
Clearer errors for bad images, before your job starts
Before provisioning, anycloud now checks your image and fails fast with an
actionable message when it has no linux/amd64 build (anycloud VMs run x86_64 —
with docker buildx build --platform linux/amd64 … --push guidance), doesn't
exist, or isn't accessible — instead of failing partway through the deployment.
anycloud update restarts a running API server
If a local API server is running when you run anycloud update, it now offers to
restart it on the new version (on the same port) so you pick up the update right
away. At a terminal you're asked to confirm (default yes); in non-interactive
contexts it restarts automatically. Previously you had to remember to run
anycloud api stop and anycloud api start yourself, or the server kept
serving the old version.
anycloud submit is now fully interactive
Running anycloud submit in a terminal without the cloud flags used to exit with
a "Cloud config required" error. It now guides you through the whole job: it
prompts for credentials (auto-selecting when you only have one), then for a
compute type from a searchable list of your cloud's instances — GPU options first,
then CPU instances labeled with vCPUs, memory, and price — and, when the instance
supports it, whether to run on-demand or spot. Pass --credentials, --vm-type,
--gpu-type, or --spot to skip the matching prompt.
Fixed: clearer error when requesting spot on a cloud that doesn't support it
Submitting a spot job to a provider without spot instances now returns a clear client error instead of a generic server error.
0.1.23
Fixed: slow failover when a region is out of capacity
When a region had no capacity for the requested instance type, a deployment could spend several minutes on each retry before trying another region. Deployments now fail over to the next region with availability promptly.
Fixed: deployments could get stuck while downloading the image
If the SSH connection dropped while the container image was being pulled, a
deployment could wedge in the downloading state. Image pulls now run
detached on the VM, so a dropped connection no longer stalls progress.
0.1.22
Fixed: CLI failed to start on fresh installs
A packaging bug in 0.1.21 caused the anycloud CLI to exit immediately on
startup with a Cannot find module error. The CLI now starts normally. If
you're on 0.1.21, reinstall with:
curl -fsSL https://get.anycloud.sh | bash
0.1.21
anycloud ssh and anycloud logs removed
The anycloud ssh and anycloud logs commands have been removed. Use
anycloud exec <id> "<command>" to run a command in your job's execution
environment, and anycloud status <id> --verbose for lifecycle, errors, and
captured output. On providers that run your image directly as the workload,
anycloud exec now runs your command in that environment rather than wrapping it
in a container exec.
Vast spot (interruptible) instances
anycloud submit --spot now works on Vast. Spot runs bid on Vast's
interruptible marketplace at the live offer price, and anycloud detects when an
instance is reclaimed and reprovisions a fresh one to keep the job going.
Vast hosts have no storage of their own, so spot on Vast requires a checkpoint bucket on a cloud that does. Point it at storage credentials with the new flags:
anycloud submit my-image --spot
--checkpoint-storage-credentials my-aws
--checkpoint-storage-region us-east-1
Checkpoints your job writes sync to that bucket, so a reprovisioned instance
restarts with them already in place. The bucket is named after the deployment and
is removed when the deployment ends — keep it with --persist-bucket.
Vast also now appears in anycloud gpus and anycloud pricing, including the
cross-cloud anycloud gpus --type comparison.
Bring your own Docker image
anycloud build, Client.build(), and the Python anycloud.Image builder API have been removed. Build and push Docker images locally or in CI, then submit the resulting image reference with anycloud submit or Client.submit(). See Docker — Building and Pushing for local and GitHub Actions examples.
anycloud login now also attempts a best-effort local docker login ghcr.io when Docker is installed, using the same GitHub token, so GHCR pushes work without setting up a separate registry credential.
Explicit image baking and pruning
anycloud submit --bake and Client.submit(..., bake=True) now explicitly opt in to creating baked VM images. Normal submits can still reuse a matching baked image when one exists, but they no longer create new baked images by default. Use anycloud images prune to remove stale baked images from cloud accounts.
Stricter git source checks for @anycloud.function()
The Python function decorator now rejects dirty working trees and commits that are not pushed to origin before submission. Remote execution clones from GitHub at the submitted commit, so local-only changes cannot be reproduced on the VM.
Agent session labels use Claude Code titles
Agent-scoped CLI output now shows the readable Claude Code session title when one is available, instead of only showing the raw session identifier in list and spend-control views.
Interactive credential setup improvements
anycloud credentials new now better guides AWS and Azure setup from local CLI state, including browser login paths, profile selection, and clearer cleanup when deleting credentials.
anycloud quota request now raises Azure public-IP limits
Azure caps public IP addresses per subscription per region (100 by default), and every VM consumes one — so a fleet could stall on the IP cap even with plenty of vCPU quota. Two changes: anycloud quota request now files a public-IP increase alongside the vCPU request for each region, and hitting the public-IP cap is now treated as a quota error (the region backs off and the anycloud quota hint is shown) instead of being retried indefinitely.
Guided anycloud quota request picker
Running anycloud quota request with no arguments in a terminal now walks through credential → GPU quota target (choose specific types or all GPU families) → GPU instance type(s) when needed (searchable multi-select, with Ctrl-A to toggle all) → quota type(s) (on-demand, spot, or both) → region (or all regions), filing a request per selected type. Passing --spot or --region skips the matching prompt; explicit vmType/--gpu invocations and non-TTY/--json usage are unchanged.
0.1.20
Vast.ai provider support
Vast.ai is now available as a GPU marketplace provider. Add a Vast credential with anycloud credentials new, submit jobs against Vast GPU offers, and use the normal logs, exec, ssh, and bucket-sync flows through Vast's NAT'd SSH endpoints.
Config profiles removed in favor of inline flags
anycloud config and ANYCLOUD_CONFIG profiles have been removed. Pass submit settings directly with flags such as --credentials, --gpu-type, --vm-type, --region, and bucket options. Existing docs and tutorials now use inline submit flags.
anycloud images browses GHCR images
anycloud images now lists and filters images from GitHub Container Registry, with interactive selection in a TTY and --json / --only-refs output for scripts. The build flow also gained a credential picker so image builds can target the intended cloud account.
AWS, Azure, and prebake reliability
AWS provisioning now handles multi-VPC security group selection correctly and avoids default-VPC security group APIs. Azure capacity failures rotate more cleanly, and prebake image lookup now keys on image digest so reused tags resolve to the right baked image.
0.1.19
Agent-scoped list, cost, and spend controls
anycloud list and anycloud cost now scope to the detected agent session when appropriate, matching the per-session throttle and budget controls. Spend-cap block alerts are debounced so queued deployments do not spam repeated notifications while waiting for capacity or budget.
Quota and capacity retry routing
Quota failures are now classified by region versus account scope, so the optimizer blocks the right retry target instead of over- or under-rotating. AWS provisioning also handles shared IAM bootstrap retries and non-default networking paths more reliably.
Cross-cloud bucket and checkpoint credential fixes
Bucket sync, checkpoint restore, and cross-cloud storage credentials now use the credential scoped for the actual storage operation. This avoids leaking AWS S3 credentials across provider boundaries and makes cross-cloud checkpoint flows more predictable.
0.1.18
Auto-retry jobs whose container can't see the GPU
If a GPU job's container exits with CUDA_ERROR_NO_DEVICE in its logs — the host booted without visible GPUs — the deployment now retries on a fresh VM instead of being marked errored. The previous behavior required a manual anycloud resubmit for every occurrence. The retry uses the standard failed-deploy backoff and exhaustion limits.
Notifications digest skips the first-run backfill
The first time the digest monitor runs after enabling notifications on a host, it marks today as the starting point and posts nothing. Previously the next 15-minute tick would post a half-empty digest of whatever happened to be in the DB before notifications were configured. Your first real digest now lands the morning after your first full UTC day with notifications enabled.
Interactive prompts for budget, throttle, notifications
Running anycloud budget set, anycloud throttle set, or anycloud notifications enable slack with no arguments now prompts for the missing values (cap, window, webhook URL) when stdin is a terminal. Flag-only invocations behave the same as before, and piped or CI usage (no TTY, or CI=true) still exits with the previous error instead of hanging.
0.1.17
status now returns the full VM history (breaking)
/v1/status and anycloud status --json now return vms (every VM ever associated with the deployment, terminated rows included) instead of vmStatuses (active only). Each entry has a new endedAt field — null for live VMs, a millisecond timestamp for terminated ones. Live VMs still carry the container and rclone health-check fields; terminated rows are provisioning metadata only. This lets you read prebakedImageId, region, and cloudId for VMs after they've been cleaned up — previously those were only visible during the deployment's running window.
The human-formatted anycloud status output is unchanged by default (terminated VMs are hidden). Pass --verbose to see them, marked (terminated). The Python SDK's status_response.vm_statuses is now status_response.vms and includes terminated rows; SDK helpers like Job.exec() and Job.logs() filter to live VMs automatically.
If you have scripts that grep for vmStatuses in status --json output, rename to vms and add select(.endedAt == null) if you want the old "active VMs only" semantics.
Spend controls: anycloud throttle and anycloud budget
Two new commands cap spend by blocking new dispatches when usage exceeds a limit. Running jobs are never killed — only queued work pauses.
anycloud throttle set 20— burn-rate cap ($/hracross in-flight VMs, plus the candidate). Set--agent-sessionto cap each agent run independently instead of account-wide.anycloud budget set 100 --per day— calendar-window cap (day, week, or month). Same--agent-sessiontoggle.
Blocked deployments stay queued with a reason shown inline in anycloud list and anycloud status, and auto-dispatch once running VMs end (throttle), the calendar resets (budget), or you raise the cap. See Spend Controls for the full surface.
anycloud db query / db schema for read-only DB inspection
Two new commands let you (or an agent) inspect the local API database without leaving the CLI. anycloud db query "<sql>" runs a read-only SELECT / WITH / EXPLAIN / PRAGMA — writes are refused at the SQLite engine level — and emits rows as JSON with --json. anycloud db schema [table] introspects tables, columns, foreign keys, and indexes; pair the JSON form with db query to answer "which deployments are stuck and why" without poking the SQLite file directly.
anycloud cost switches to real billed cost
anycloud cost <id> now shows the real cost pulled from your cloud provider's billing API once the bill settles (~24 hours after a deployment ends). Until then — or if your account doesn't have billing-read permissions — it falls back to the catalog estimate as before, marked (est.).
To enable this, the cloud credentials anycloud uses now need a small additional permission:
- AWS: add
ce:GetCostAndUsageto the IAM policy. Activate theanycloud_deploymentcost-allocation tag once (Billing → Cost Allocation Tags → activate, oraws ce update-cost-allocation-tags-status --cost-allocation-tags-status TagKey=anycloud_deployment,Status=Active). - Azure: grant the service principal the built-in
Cost Management Readerrole on the subscription. - GCP: enable Cloud Billing BigQuery export with resource-level detail, grant the service account
roles/bigquery.dataVieweron the billing dataset, and pass the dataset toanycloud setup gcp.
Without these, nothing breaks — anycloud cost keeps showing the estimate.
anycloud notifications enable slack — daily Slack digest of usage
The API container can now post a once-a-day summary to a Slack channel you choose, aggregated from your local deployment history (~/.anycloud/api.db) and sent directly from your machine to the webhook.
anycloud notifications enable slack --webhook https://hooks.slack.com/... posts a test message before saving so a typo'd webhook is caught immediately. The digest covers total spend, count by terminal state, preemption rate, median runtime, and active users. anycloud notifications status / test slack / disable slack round out the surface. Setup details in docs/guides/notifications.md.
0.1.16
MCP secrets tools
Three new MCP tools — secrets_list, secrets_create, secrets_delete — let an agent manage named secrets (env-var bundles used via secrets=[...] on submit). Mirrors the existing CLI secrets new/list/delete. secrets_delete accepts force=True to override the safeguard that blocks delete while non-terminal deployments still reference the secret.
CLI catalog introspection
Four new commands surface the same cloud catalog the Python SDK already exposed, so you can pick a region or VM type before you submit:
anycloud regions <provider> [--vm-type <type>] [--spot]— list available regions. With--vm-type, narrows to regions that offer that VM type, sorted cheapest first.anycloud vm-types <provider> <region> [--accelerator <gpu>]— list VM types in a region, optionally filtered to ones with a specific accelerator.anycloud gpus <provider> [--type <gpu>]— list available GPUs, or available counts for a specific GPU when--typeis given.anycloud pricing <provider> <vm-type> [--region <r>] [--spot]— on-demand or spot price per region.
All four accept --json for scripting and accept the provider name case-insensitively (aws, AWS, Aws all work).
anycloud bucket upload / download
New CLI commands stream files in and out of an S3, GCS, or Azure Blob bucket using a credential you've already registered with anycloud credentials new:
anycloud bucket upload my-bucket ./data.bin data/in.bin --credentials prod-aws
anycloud bucket download my-bucket data/out.bin ./out.bin --credentials prod-aws --region us-east-1
The same routes back the Python SDK's Bucket.upload() / Bucket.download(), so the CLI and SDK now go through one code path. As part of that switch, the Python SDK no longer needs cloud filesystem libraries — the [aws], [gcp], and [azure] extras have been removed from anycloud-sdk because s3fs, gcsfs, and adlfs are no longer used. Bucket I/O now requires the credential to be registered with anycloud credentials new (it could previously work with inline CloudConfig credentials passed to Client(...)); construct your client with Client(credentials="<name>") instead.
anycloud cost --json for scripts and agents
anycloud cost now accepts --json. Without an id, it emits the aggregate report { periodMs, totalCost, totalDurationMs, totalJobs, deploymentsWithoutPrice, byProvider }; with an id, it emits the per-deployment fields (id, image, cloudProvider, region, vmType, spot, totalCost, durationMs, ratePerHour). Previously the only output was a formatted table, so anything calling anycloud cost from a script had to grep currency strings out of stdout.
anycloud list gains exact-match filters and machine-friendly output modes
anycloud list now supports --status <state>, --provider <cloud>, --csv, and --only-ids in addition to the existing substring -f, --filter and --json. Multiple predicates AND together. --csv emits a header row plus one row per deployment (id,state,cloudProvider,region,vmType,image,spot,startedAt,completedAt,totalCost,deploymentType), useful for piping into spreadsheets or awk. --only-ids emits one deployment ID per line and skips the table, useful for anycloud list --only-ids --status running | xargs anycloud terminate and similar batch operations.
--json output is now compact
Every --json flag in the CLI (list, status, cost, credentials list, config list, quota) now emits a single line of compact JSON instead of pretty-printed JSON with two-space indents. Equivalent payload, ~30% fewer bytes. jq . and any other JSON parser handle it identically.
0.1.15
Failed provisioning attempts no longer orphan cloud resources or pollute anycloud list / cost
When a VM provisioning attempt failed partway through (for example, Azure created the NIC and Public IP but the VM create itself errored), the rows were marked "ended" in anycloud's bookkeeping even though the cloud-side resources were still there — slowly eating the 100-Public-IP-per-region Azure quota until new submits started failing on quota errors. The same rows also showed up as live VMs in anycloud list and accrued duration in anycloud cost. Cleanup now waits for the cloud to confirm each resource is gone before marking it ended (the cleanup monitor keeps retrying anything the cloud rejected), and failed-attempt rows are filtered out of the list and cost aggregates.
status always renders the deployment header
anycloud status <id> no longer falls back to ❓ unknown with a "deployment not found in deployments list" hint when the id is older than the picker window or otherwise missing from the recent list. The metadata (image, cloud, region, VM type, age) now comes back with the status response itself, so the header is correct on the first call and the second round-trip is gone.
Security: deployment IDs are no longer probeable across users
Knowing another user's deployment id no longer lets you fetch their SSH key (status), terminate their job (terminate), or resubmit it (resubmit). All three now reject cross-user ids with the same "deployment not found" response they return for ids that genuinely don't exist, so an authenticated caller can't enumerate other users' deployments either. Pre-existing pings against your own deployments are unchanged.
0.1.14
anycloud cost now works for jobs submitted without a pinned region
anycloud cost reported $0.00 for jobs submitted without an explicit region — the common case, since omitting a region enables multi-region failover. The hourly rate is now captured on each VM at provision time (when the region is finally known) and cost is summed across the deployment's VMs, instead of relying on a single rate stored at submit. Multi-region retries that land in different-priced regions are now reflected accurately in the total.
0.1.13
Multi-region Azure submits stop retrying regions the subscription can't use
When Azure rejects a region with a "not permitted for subscription" or "not available for resource group" error (e.g. Jio India regions on most commercial subscriptions), the deployment now skips that region for the rest of its lifetime instead of cycling back to it every few minutes. Previously, multi-region jobs could exhaust their retry budget bouncing between forbidden regions and never reach the regions the subscription actually has access to.
0.1.12
--persist-bucket retains the spot checkpoint bucket without keeping the VM
anycloud submit --spot --persist-bucket skips the auto-deletion of the checkpoint bucket on job completion. Independent of --persist — the common shape is an ephemeral VM (no --persist) plus a retained bucket, so a later anycloud resubmit <id> brings a fresh VM up against the same checkpoint contents without paying for an idle one in between. The flag is a no-op (with a warning) on non-spot deployments since they have no checkpoint bucket. Cleanup is manual: aws s3 rb s3://<id> --force or the equivalent for your provider — the existing orphan reaper leaves retained buckets alone because they aren't tagged as ended.
0.1.11
Legacy credential arrays
Earlier builds briefly accepted a list of named compute credentials. That shape has been superseded by pinned-or-unpinned compute credentials: pass one --credentials <name> to pin compute, or omit it so anycloud chooses from saved named credentials.
Legacy array rows are normalized to unpinned compute during migration.
0.1.10
Ordered fallback pools for vmType and gpuType
Both fields now accept an array as well as a single string. The provisioning scheduler expands every entry into the candidate pool — for gpuType, each alias is resolved into all interchangeable instance types — and falls over in order when the primary is quota-blocked or unavailable. CLI flags --vm-type / --gpu-type are now repeatable on submit, config new, and config edit; anycloud.yaml profiles accept a list under either field. The config new wizard now uses a multi-select picker (Space to mark, Enter to confirm — selection order is fallback order). The two fields are still mutually exclusive (only one of vmType / gpuType may be set, but each can itself be a list). The original list is preserved on the deployment row for display and retries.
quota request always asks for one more instance of headroom
anycloud quota <vmType> now files a ticket every time you run it (unless an in-flight request is already pending for the same family + region). The previous "only when exhausted" trigger missed the common fresh-subscription case — limit=0, usage=0 looked fine but the user couldn't launch a single VM. The new target is max(currentUsage + vCPUsPerVM, currentLimit × 2, vCPUsPerVM) — at minimum, one more instance's worth of capacity, with a doubling floor on top so re-running keeps growing the ceiling. AWS applies the same rule with currentUsage treated as 0 (Service Quotas doesn't expose live usage).
If every surveyed region already has a pending ticket for the family, the tail reads No new tickets filed — every surveyed region already has a pending quota request for <vmType> on <cloud>. instead of No actions taken..
quota picks credentials, not clouds
quota request and quota status now prompt for a credential rather than a cloud — credential implies cloud, so the second picker round-trip is gone. With a single AWS or Azure credential the picker is silent; with multiple, an autocomplete labelled <name> (<cloud>) appears. --credential <name> still bypasses the picker. Credentials for clouds without quota support (GCP, Lambda, Local) are filtered out and surface a clear error instead of running the picker only to fail later.
Breaking: --cloud removed from quota subcommands
anycloud quota --cloud <aws|azure> no longer accepts the flag on either request or status. Cloud is now derived from the resolved credential or, for request, the vmType prefix. Pass --credential <name> to pin to a specific account.
0.1.9
Picker fixups
- Restore
-a/--allonstatus(regressed when the picker came back) so the picker can widen past the last 24h. --jsonnow refuses the picker rather than dumping its stdout chrome into the JSON pipe.
Multi-region quota request / quota status
--region is now optional on both subcommands. Omit it to fan out across every region in the cloud's catalog (AWS narrows to regions where the vmType is offered; Azure narrows to regions where the family is exhausted). Per-region calls run in parallel via Promise.allSettled, so wall-clock matches a single-region invocation. Re-runs stay idempotent thanks to the existing per-region dedup.
When the fan-out hits an AWS region that is disabled-by-default (e.g. me-central-1, ap-east-1, af-south-1), anycloud submits the AWS EnableRegion call for it. Opt-in is asynchronous — the quota request for that region is deferred and the entry comes back as SUBMITTED with optInAction: enabling. Pass --region if you'd rather not opt anything new in.
Interactive GPU instance picker
Run anycloud quota request with no vmType and no --gpu in a TTY to get an interactive cloud picker followed by an autocomplete list of GPU instance types from the catalog (e.g. g6e.48xlarge — 8× L40S (192 vCPUs)). Non-TTY / --json flows are unchanged: an explicit vmType or --gpu is still required.
0.1.8
Smarter blocks for disabled regions
When a provision fails because the region's quota is 0 or the subscription can't deploy there at all (AWS OptInRequired, Azure ProvisioningDisabled / LocationIsOfferRestricted), the optimizer blocks that region for 6 hours instead of the 30-minute generic quota block — so retries stop hammering regions that won't come back without a support ticket.
Named Secrets
New primitive for env vars you don't want visible in API responses. anycloud secrets new|list|delete manages named bundles that are encrypted at rest, never returned by the API, and injected into containers at run time via --secret <name> (CLI) or secrets=[...] (Python SDK). Update a secret and resubmit to rotate — no need to edit every call site. See the Secrets guide.
Sensitivity warning on --env
When you pass a likely-sensitive key via --env (e.g. HF_TOKEN, API_KEY, anything matching token / secret / password / key), the CLI prints a one-line warning pointing at anycloud secrets new. The submit still proceeds; the warning is advisory.
Version warning
The CLI checks its own version against the current public release and prints a warning when you're behind. Keeps users from debugging issues that were already fixed upstream.
Quota dashboard links
anycloud quota status now surfaces structural console URLs (AWS Service Quotas, Azure portal) for each case, so you can jump straight to the provider's UI.
Smarter quota request
anycloud quota request detects partial grants and skips re-requesting quota that's already been submitted or granted, so re-runs are idempotent.
Broader Azure Region Coverage
Azure catalog now pulls the full list of physical regions via the subscription-wide /locations endpoint instead of per-SKU locationInfo, which was silently gated on per-SKU enrollment. Measured on one subscription: 43 → 58 regions, ~33k → ~55k SKU rows.
--json on read-shaped commands
status, list, config list, and credentials list now accept --json. Chrome output routes to stderr; stdout is the pure JSON payload, so anycloud list --json | jq just works. credentials list --json emits only {name, cloudProvider} — secret fields never cross the boundary. Empty results return [] instead of the prior "No X found" strings.
Interactive deployment picker (TTY only)
Deployment ID is now optional on status, logs, exec, ssh, terminate, and resubmit: omit it in a TTY for an interactive picker (multi-select on terminate and resubmit). This walks back part of the "Non-Interactive CLI" change from 0.1.7 — non-TTY/CI still requires an explicit ID or ANYCLOUD_DEPLOYMENT_ID, so scripts and agents are unaffected.
Azure-safe deployment ID cap
Max deployment ID length lowered 40 → 28 to leave room for the -${index} suffix Azure appends to VM/NIC/public-IP names. Auto-generated IDs also tightened so they fit under the new cap.
0.1.7
Batch Submission in the Python SDK
Submit many jobs in parallel from a single call, with first-class partial-failure handling. The decorator path gets a map helper for fan-out workloads.
More Resilient Prebakes
Cached images survive upstream base-image rotation, and bake outcomes now show up in deployment status instead of disappearing into logs. CLI status also surfaces when a deploy hits a prebake cache.
Quota Requests From the CLI
Request and check cloud quota directly from the CLI, with AWS now supported alongside Azure. Deployments that exhaust retries on a quota error point you at the new commands.
Credentials Through the API
The CLI and MCP no longer touch plaintext credentials on disk. New MCP tools cover importing existing cloud credentials and generating least-privilege ones.
Non-Interactive CLI
Every CLI command is now flag- and env-driven — no prompts, no pickers, no wizards. Better for scripts, CI, and agents.
Steadier Region Rotation
Region or SKU mismatches from a cloud no longer fail a deployment outright; the optimizer rotates instead.
0.1.6
More Resilient Image Pulls
Faster retries on transient pull failures and gentler post-provisioning backoff.
Expanded MCP Server
Added list_gpus, list_gpu_counts, credentials_get, bucket_upload, and bucket_download tools.
Smarter Region Rotation
When every target is temporarily blocked, the optimizer rotates across regions instead of stalling on the cheapest one. Block TTLs are also preserved at their maximum, and InvalidTarget blocks are capped at 6 hours.
Strict CloudConfig Validation (Python SDK)
CloudConfig now rejects unknown keyword arguments instead of silently ignoring them.
0.1.5
Per-Bucket Storage Credentials
Input and output buckets can now use different cloud credentials and regions. The shared storageCredentials/storageRegion fields have been replaced with per-bucket equivalents (inputStorageCredentials, outputStorageCredentials, etc.).