Journal indexDockup / field note
Note / preview-environment-costs

What Preview Environments Actually Cost

Preview environment cost grows with open pull requests, not with team size. Learn where the spend hides, which parts to share, and how to expire previews so five open PRs are not five stacks.

Preview environments are one of the highest-leverage things a team can turn on. A reviewer clicks a link and uses the change instead of reading a diff and imagining it. Design catches problems before merge. QA stops being a phase.

They are also the line item most likely to quietly triple your bill, and the reason is arithmetic that nobody does at the moment they enable the feature.

The arithmetic

Preview environment cost scales with the number of open pull requests, not with the number of people on the team or the number of merges.

A four-person team with a healthy review culture might have five to eight PRs open at any moment. If each one provisions a full copy of your stack, you are running five to eight copies of production alongside production. A stack that costs $30 a month to run is now costing $180–$270, and none of that appeared in anyone's estimate, because the estimate was about one environment.

Worse, open PRs correlate with the times you can least afford surprises: before a release, during a refactor, when someone is on holiday and their branch sits open for three weeks.

Where the money actually goes

Not every part of a preview costs the same, and knowing which is which is what makes the cost controllable.

Application containers — moderate, and worth it. This is the part you actually want. It is also the part that scales down well, because a preview does not need production's memory.

Databases — the expensive part. A dedicated database per preview is the single largest contributor, and it is usually the least necessary. Most reviews do not need an isolated database; they need a database with plausible data.

Build minutes — invisible and cumulative. Every push to an open PR rebuilds. A branch with forty commits over two weeks builds forty times. This is real spend that never shows up as a running resource, so it escapes the mental audit entirely.

Egress — small per preview, large in aggregate. Preview URLs get discovered and crawled. A crawler pulling your assets from eight preview environments is doing eight times the work it does on production, and you are paying for all of it.

Four things that cut it without losing the value

Share the database

For the majority of changes, previews can share one database seeded with representative data. Reserve isolated databases for the PRs that actually need them — migrations, schema changes, anything destructive.

The rule that works in practice: isolated database only when the PR touches the schema. Everything else shares.

Scale the preview down

A preview serving one reviewer does not need production's resources. Half the memory and a fraction of the CPU is usually invisible to the person reviewing and materially cheaper.

dockup resources my-project/my-api --memory 512 --cpu 0.5

Expire them

The single highest-impact change. A preview should not outlive its pull request.

Automatic teardown on merge or close is table stakes. What catches teams out is the abandoned PR — the branch someone opened, got pulled off, and never closed. Those environments run for months.

A maximum age is the backstop worth having: any preview older than, say, fourteen days gets removed regardless of PR state. If someone needs it back it is one command.

Keep them out of search

Preview URLs get indexed. That is bad for two reasons — duplicate content competing with your production site, and crawler traffic you pay for on environments nobody is using.

dockup noindex my-project/my-api --on

On Dockup, PR previews are per service and can be enabled or disabled explicitly rather than being a global setting you inherit:

dockup pr-preview my-project/my-api --on
dockup preview list my-project/my-api --json
dockup preview delete 128 my-project/my-api

Listing them is the part teams skip and then regret. Environments you cannot enumerate are environments you are paying for without knowing.

The audit worth doing once a month

Three questions, five minutes:

  1. How many previews are running? Compare that to how many PRs are actually open.
  2. How old is the oldest? Anything past two weeks is almost certainly abandoned.
  3. Which have their own database? Anything that is not a schema change probably does not need one.

Most teams find at least one environment from a PR that was merged months ago, still running, still billing.

Getting the value without the surprise

None of this is an argument against preview environments. It is an argument for treating them as infrastructure with a lifecycle rather than as a checkbox.

The teams that get this right do three things: previews scale down, previews expire, and previews share what they can safely share. That usually keeps the whole preview footprint under the cost of a single production service — which is the price at which it is obviously worth it.

The teams that get surprised are the ones who enabled it once, correctly, and never looked at the list again.

Frequently asked questions

Do preview environments cost as much as production? Per environment they can, if they are provisioned identically. Scaled down and sharing a database, a preview typically costs a fraction of production.

Should each preview have its own database? Only when the change touches the schema. Sharing one seeded database covers most reviews and removes the largest cost.

What happens to a preview when the PR closes? It should be destroyed automatically. If it is not, you will accumulate environments from PRs nobody remembers.

Do preview environments hurt SEO? They can, if they get indexed — duplicate content competing with your production pages. Mark them noindex, which also stops crawlers generating traffic you pay for.