Previews, production, promotion, and rollback
How a deployment becomes production, how to go back, and the addresses and limits of each deployment.
The key idea: deployments never change, addresses move
Every ntro deploy creates a new deployment, and a deployment never changes once created (it is immutable). Your production address my-app.ntro.run works like an arrow pointing at "the deployment to show right now".
- Promote: move the arrow to a preview you have checked.
- Roll back: move the arrow back to an earlier deployment.
Neither rebuilds anything; they only move the arrow.
Production and preview
| Situation | Result |
|---|---|
| The app's first deployment (no production deployment yet) | Production |
| Any later default deployment | Preview |
--prod (or --target production) | Production |
--preview (or --target preview) | Preview |
Use only one of --prod, --preview, and --target. A preview never becomes production on its own.
ntro deploy . --preview # deploy a preview
ntro deployments list --target preview # list previews only
ntro deployments show <short-id> # deployment detailsDeployment addresses
Each deployment has several addresses.
| Address | Format | Points to |
|---|---|---|
| Production URL | my-app.ntro.run | The current production deployment (changes on promote and rollback) |
| Revision URL | my-app-<short-id>.rev.ntro.run | That one deployment, pinned forever |
| Branch URL | my-app-git-<branch>.rev.ntro.run | The latest ready deployment of that Git branch |
| Custom domain | www.example.com | The current production deployment (Custom domains) |
Branch URLs exist only for deployments with Git branch information (for example from the GitHub integration), including those built from the production branch. Deploying from Git explains how branch names become addresses.
Changing the app slug breaks old ntro.run addresses immediately
When you change the slug in app settings, the production, revision, and branch URLs all switch to the new slug and the old addresses stop working right away. Custom domains are unaffected. If scripts use --app <old-slug>, switch them to the new slug or the app ID. Folders linked with ntro link store the app ID, so they do not need relinking.
Short IDs
The <short-id> in a revision URL is chosen like this. Once assigned, a deployment's short ID never changes.
- Deployments with a Git commit: the first seven characters of the commit SHA (lowercase). Uncommitted changes in the working tree do not matter; the commit SHA is used. If the ID is already taken in the same app,
-2,-3, and so on are appended. - Deployments without Git information: seven random characters, extended up to 12 on a collision.
Short IDs are unique only within an app. Another app may have the same short ID, but its address starts with a different slug, so the URLs never clash.
Promote, roll back, redeploy
ntro promote <short-id> --yes # make this deployment production
ntro rollback <short-id> --yes # send production back to an earlier deployment
ntro redeploy <short-id> --preview # create a new deployment from the same files
ntro logs <short-id> --follow # watch build and deployment events| Command | What it does |
|---|---|
promote | Makes an existing ready deployment production. It does not create a new deployment. |
rollback | Points production back at an earlier ready deployment. |
redeploy | Creates a new deployment from an existing deployment's files. |
logs | Shows events from the build and deployment process, not your app's request logs. |
promote and rollback ask for confirmation first. Leave out --yes to confirm in the terminal; add it in CI and scripts.
When you change compute settings
On a normal deploy, compute settings such as regions, tier, instance limits, and port can come from several places. For each field, the first value found in this order wins:
- CLI flags (direct uploads with
--local,--image, or--bundle-dironly) nitroship.json- App settings saved through App Settings > Compute in the console or the compute settings API
- Platform defaults
These values are locked in when the build starts, and each deployment records where every value came from (flag, file, app, or default). That is why changing console settings leaves existing deployments as they are.
Console/API editing is always allowed, even for fields set in nitroship.json or by CLI flags. To apply saved app settings, press Apply now in the console. It redeploys current production without rebuilding: every non-null app setting replaces the previous deployment's value and gets source app, including fields previously sourced from the file or flags. Fields left unset in app settings retain their previous values. Old deployments created before source records existed must be rebuilt.
In App Settings > Compute, a field with no app setting whose production value comes from nitroship.json or a CLI flag is prefilled with that value. Saving without changing a prefilled field leaves it unset in app settings.
On every normal deploy, nitroship.json re-applies its declared fields over console/API settings; supported CLI flags still take precedence over the file. Apply now overrides those values only for that redeploy, until the next normal deploy restores the precedence above.
For how concurrent requests share an instance's memory and what happens to local caches as instances scale, see Instances and shared memory.
Cleanup of old deployments
The current production deployment and the ten most recent ready deployments are always kept, as is any deployment an active branch URL points to. Older deployments may become pruned. A pruned deployment cannot be opened at its revision URL, promoted, or rolled back to.
Size limits
Limits follow the plan of the team that owns the app; teams without an assigned plan use the default plan. Units are decimal (1 MB = 1,000,000 bytes).
| Limit | Free | Pro | Applies to |
|---|---|---|---|
| Function request body | 4.5 MB | 4.5 MB | Function (server) invocations |
| Function response body | 4.5 MB | 4.5 MB | Function responses with Content-Length |
| Total source size | 100 MB | 1 GB | Source uploads from default ntro deploy |
| Source file count | 15,000 | 15,000 | Source uploads from default ntro deploy, and Git builds |
| Function bundle | 250 MB | 250 MB | The one deployment bundle holding all functions (bundle.tar) |
- Source size is the sum of uncompressed file sizes, not the transfer size.
- File count includes only regular files outside
.git/, not folders or symlinks. The 100,000-file limit on output for--localdirect uploads is separate. - Streaming responses (SSE and other responses that do not declare a length) have no response body limit. Request bodies are limited even while streaming.
Going over a limit returns HTTP 413 with one of source_too_large, source_too_many_files, function_bundle_too_large, or function_payload_too_large. The message shows the measured size, the limit, and the plan.
API reference: a deployment's url and urls
Deployment list and detail API responses have two address fields. The console's app overview and deployment details show the same addresses.
url: one representative address. For the current production deployment, the earliest-registered active custom domain, ormy-app.ntro.runif there is none. For other deployments, the revision URL.urls: every address currently pointing at this deployment, in this order: active custom domains (by registration), the production URL (if it is production), the branch URL (if it is that branch's current target), and the revision URL. When a branch URL moves to a newer deployment, it drops out of the older deployment'surls.
If a deployment is not ready or has been pruned, the listed addresses may not actually serve it.