Most rollbacks are rebuilds in disguise. You revert a commit, wait for CI, wait for the build, and hope the thing that worked last Tuesday still builds the same way today. When the site is down, that is the slowest possible fix.
Deployments are immutable
On Sites, a deployment is a folder of files that never changes after it is uploaded. Publishing doesn’t overwrite the previous build — it adds a new deployment next to it and moves the live pointer. Rolling back moves the pointer again. Nothing is copied and nothing is rebuilt.
$ subnomic sites deploy --prod
312 already stored, 14 to upload
https://blog.subnomic.app
$ subnomic sites rollback
The live deployment and the ten newest builds are kept, along with anything published in the last couple of hours, so there is always something to go back to.
Every build has an address
A deployment answers at its own address whether or not it is live — blog--<id>.subnomic.app. That is what a preview is: the exact bytes that would go live, openable before they do. Previews are served with noindex, so search engines don’t pick up a copy of your site.
A preview is unguessable, not private. If a build shouldn’t be seen, protect the site with a password or workspace sign-in — the protection covers every preview too.
Rules roll back with the files
_redirects and _headers belong to the deployment they shipped in. Roll back, and the old rules come back with the old files — there is no separate configuration that drifted while nobody was looking.
Only what changed is uploaded
Files are hashed on your machine before anything is sent, and anything the workspace already stores is reused. The second deploy of a large site uploads a handful of files, which is what makes deploying often cheap — and deploying often is what makes each rollback small.
The URL is the only thing on stdout
URL=$(subnomic sites deploy --prod) in a pipeline gives you a URL, not a progress log. There is a whole post about that: Only the URL on stdout.