Skip to content
runlot

Preview deployments

runlot deploy --preview puts the same bundle at a second address with its own database, copied from the project's newest backup.

runlot deploy --preview <name> puts the same bundle you would have deployed to production at a second address. That address gets its own Postgres, copied from the project's newest backup generation, so you can run a migration or wipe a table there without touching production.

runlot deploy --preview feat-42
Uploading… (31.0 KiB)
Deploying…
Branching the database from backup 3/17…
Preview feat-42 is ready.
  https://feat-42--shop.wickedev.runlot.app

The address

The preview name and the project name are joined with -- into one label.

<preview>--<project>.<org>.runlot.app

So feat-42 on the project shop in the organization wickedev is served at feat-42--shop.wickedev.runlot.app. Both names are at most 30 characters.

One label instead of two is what keeps a preview inside your organization's certificate, so it serves HTTPS from the moment it is ready. A project name can never contain --, so a preview address can never collide with a real project's.

What the database is

--db decides what env.db connects to.

--dbWhat the preview gets
branch (default)Its own copy of the database, poured from the project's newest backup. Writes stay in the preview.
sharedThe production database. No copy is made.
noneNo env.db at all. For static and API-only previews.
--db shared points the preview at production. A migration you run there is a migration in production, and a DELETE there is a DELETE in production. Nothing stands between the two.

A branch is never merged back

Writes in a branch stay in the branch. No command merges them into production, and none is planned: a branch is a copy taken at one moment, and production has kept moving since — new rows, new ids, possibly a different schema. Deciding which side wins is not something the service can do for you.

To get data out of a branch, run runlot pg export against the preview and load the file where you want it.

Branching from an older backup

runlot deploy --preview bug-812 --from 3/15

--from takes any backup that runlot pg generations lists for the project, so a preview can start from the state before the bug. If the backups needed to reach that point are no longer whole, the deploy is rejected with 409 chain_broken.

Listing, removing, promoting

runlot preview list
runlot preview rm feat-42
runlot preview promote feat-42

rm deletes the preview and its database branch.

promote takes the preview's bundle and makes it the project's live version — a new version number, the same artifact, no rebuild. It promotes the code and never the data. Production's database is left as it is, and the branch is not merged into it. The preview stays up after a promote, so the thing you were looking at when you decided is still there.

Previews expire

A preview is deleted after it has gone 24 hours without a request on the free plan, 7 days on Pro. The clock runs from the last request, not from when the preview was created, so one you open every day stays up and one you stopped visiting goes away. Deleting a preview deletes its database branch with it.

Limits

Two previews per project on the free plan, ten on Pro. Creating one past that is rejected with 409 preview_limit; remove one you are done with, or promote it.

A preview does not count against your project limit, and it does not appear in runlot project ls or the dashboard's project grid. It is on the project's preview list instead.

Storage

A branch is a full copy of the database at the moment it was poured, not a copy-on-write snapshot. A 400 MiB project with two branches is holding 1.2 GiB. Those bytes count toward the project's database size, including the db_near_cap notification we send at 90 % of the cap.

Access and usage

A preview inherits the project's access policy: the policy is copied into the preview when it is created, so a private project's previews are private from their first request. See Deployment access control.

A preview's requests and CPU time count against the same organization budget as production. A preview under load spends what production needs, and the same 429 budget_exhausted stops both. runlot usage lists the preview separately, so you can see which one did it.

On this page