The Build Pipeline
When you hit Build, one background process turns the database into the static site and, only when everything succeeds, swaps the new files into place. Nothing upstream ever shows half of a build; the first thing a visitor sees is either the old site or the whole new one.
How a build starts
Content edits never rebuild the site by themselves. A build is dispatched from the admin dashboard, API, a webhook, or the command line. On dispatch, the system claims the build so only one runs at a time: pushing Build twice won’t start a second one; the second trigger simply reports a build is in progress. The lock clears when the build finishes (or fails), whichever happens first.
Once claimed, the builder runs in the background with your database and output directory handed to it explicitly. Depending on how it was started, the build can be the default incremental run, a forced full rebuild from scratch, or one that bypasses the safety gates for that single build. When it finishes, your configured build webhook can be notified so external systems learn of the event.
What the builder produces
The builder makes staging, a separate output/.next directory, not live. Staging stays side-by-side with the live directory until the swap. That separation means every decision about whether a build is safe happens before any live content is touched, and all staging decisions are logged with their outcome. Live output remains untouched by anything that writes during a build.
Incremental builds and what makes a run “full”
Every build starts in incremental mode unless you don’t request it or the builder decides one isn’t safe. Before staging is touched, it walks through an eligibility checklist:
- incremental was requested;
- there is a last-built timestamp, and it isn’t in the future;
- the live output directory exists and contains an index.html;
- a build fingerprint from the previous successful build is on record, still matches the current settings and theme templates (a fingerprint mismatch means a “global change”);
If any check fails, the build cleanly falls back to a full rebuild and logs the reason. When the checklist passes, staging is premounted as hardlinks from live: content files are paid for on disk only where they’re changed, and unchanged files ride along for free.
A build then re-renders only dirty content: items updated since the last build, items whose scheduled publish or unpublish time crossed since the last build, and any pages/posts depending on changed blocks or stacks. Everything else is skipped and reused from the render cache.
Rendering speed
Rendering runs multi-worker by default on the machine’s CPU count (up to 16), with a single-worker sequential mode available. Any build gets an overall time limit, and a 2 GiB write budget split across workers, so one misbehaving build can never hang the pipeline or fill the disk mid-flight.
Going live: the staging swap
When the build finishes successfully (and the promotion guard doesn’t refuse to publish it), staging is moved to live:
- The standard production layout uses a symlink: the swap is a single atomic rename, zero downtime.
- With a directory layout: a two-step rename introduces at most a brief moment between moves, safe on the same filesystem; the previous directory is retained for cleanup.
- The very first build renames the completed staging into live.
A failed swap rolls back instead of half-publishing, never leaving a broken live directory.
When things go wrong mid-flight
Any fatal condition (timeout, write-budget overflow, render errors, or a failure at promotion time) discards staging and leaves the previous output serving as-is. Signing a build manifest happens before promotion, and if signing or promotion falls back, the previous manifest is restored so an out-of-service signature never claims content that isn’t live (this gate can be relaxed only in test environments).
What each build writes to disk
After each language pass:
- Output that no longer maps to current content (deleted, unpublished, or out-of-window items) is removed, so stale URLs disappear; whether staging was hardlinked from live or freshly rendered, the kept-set of published paths governs what stays;
- the sitemap, RSS feed, and 404 page per language;
- broken internal links and HTML/a11y warnings, all recorded.
The build log captures all of it (the last 100 builds including their full output and validation reports), plus last-built timestamp that keeps incremental runs eligible until the next.