cmdz
ProductThe limitMCPPricingRegionsDocs How it works Build with an agent Security Our hardware Blog About Start free trial Log in

The chain

Six phases, and you see all of them

Detect

We read your repository: lockfiles, manifests, framework config. That produces a build plan — runtime version, package manager, install command, build command, start command — which you can see and override in a cmdz.toml if the detection got something wrong.

Build

A sandboxed builder turns the plan into an image, with a warm dependency cache from your previous build. Services your app needs — Postgres, Valkey, object storage — are provisioned in parallel, because that work does not depend on the image.

Release

The image starts in a Kata micro-VM with its own kernel. A startup probe polls until the app answers, and only then does traffic move over. If it never answers, the old version keeps serving and the deploy is marked failed.

cmdz deploy — full output
$ cmdz deploy

  queue     accepted                                    0.4s
  detect    next@15 · pnpm@9 · node 22 · prisma → postgres
            from package.json, pnpm-lock.yaml, next.config.mjs
  build     nixpacks plan → layers → image            38.2s
            cache hit: node_modules (412 MB)
  scan      no critical CVEs                           2.1s
  provision postgres-16 small · nl-rtm-1              14.0s  (parallel)
  release   kata micro-VM · 2 replicas · rolling      21.6s
  health    startupProbe ok after 3.0s
  ✓ live    https://linktree.cmdz.app                  92.1s

  DATABASE_URL injected · rollback: cmdz rollback --to 41

Ninety seconds is the target for a first deploy of a small Next.js app. A second deploy of the same app is usually well under thirty, because the dependency cache is already warm.

Detection

What we recognise, and what happens when we do not

Detection runs on your source, in this order. The first thing that matches wins, and you can always override it.

01

A cmdz.toml, if you wrote one

Explicit beats implicit, always. Anything you set in cmdz.toml — runtime version, install command, build command, start command, extra Nix packages, cache paths — overrides everything below it.

02

A Dockerfile, if you have one

If your repository has a Dockerfile we use it and stay out of the way. This is the escape hatch for anything unusual, and it is a first-class path rather than a fallback.

03

Framework detection

We recognise Next.js, Nuxt, SvelteKit, Astro, Remix, Laravel, Symfony, Django, FastAPI, Flask, Rails, Express, NestJS, Go, Rust and more, along with the package manager and the runtime version you pinned.

04

Nothing recognised

The build fails with a detect_failed error that names what it looked for and what it found, plus the three-line cmdz.toml that would fix it. It does not guess and it does not silently deploy something wrong.

Isolation

Your app gets a kernel, not a namespace.

Most platforms in this category run customer code in containers that share one kernel. That is efficient and it is fine right up until a kernel escape, at which point "fine" stops being the word.

We run every workload in a Kata Containers micro-VM: a real virtual machine with its own kernel, started by the same Kubernetes machinery as an ordinary pod. The isolation boundary is the hypervisor, not a namespace.

This matters more than it used to, because a growing share of the code running on platforms like ours was written by a model rather than reviewed by a person. Fly.io reaches the same isolation quality with Firecracker; we are not claiming to be alone in this. What we combine it with — a hard limit and a full agent API — is the part that is ours.

Read the security page

the isolation boundary
  your app
  └─ own kernel        ← the boundary
     └─ kata micro-VM
        └─ hypervisor
           └─ node (Rocky Linux 10, LUKS at rest)
              └─ our rack

  elsewhere:
  your app
  └─ namespace + cgroup
     └─ shared kernel   ← the boundary
        └─ node, with other customers

Around the deploy

The parts that make a deploy survivable

Rollback in one key

Ninety days of deploy history. A rollback re-releases a previous image that already built and already passed its health check, so it is a cutover rather than a rebuild — seconds, not minutes.

A preview per pull request

Every pull request gets its own URL with its own environment. They go to sleep on their own when nobody visits them, so having many of them costs very little, and they are cleaned up when the branch is.

Zero-downtime by default

Rolling releases with a startup probe, so traffic only moves once the new version answers. If it never answers, the old one keeps serving and you get told why.

Services attached, not configured

Adding Postgres, Valkey, object storage or a vector index injects the connection variables into your app. You do not copy a connection string anywhere, and rotating a credential does not require a redeploy.

Cron and background jobs

Scheduled tasks and queue workers are first-class workload types with their own logs and their own metrics, priced the same way as everything else.

Scale to zero, with an alarm clock

A workload that nobody is using can sleep and wake on the first request. For production apps you can set a schedule instead, so the first visitor of the morning never pays the cold start.

Point it at a repository and see.

The first deploy tells you more than this page can, and it comes out of the € 10 of credit you start with.