Anatomy of a 3-Cent Preview Environment
The arithmetic, the machinery, and the part that rots

Around three cents. That's the ballpark lifetime cost of the thing that most changed how code review feels on Light Cloud: a full, disposable copy of the application, on its own URL, for every branch. Not a screenshot bot, and not a staging server you book in a spreadsheet. A real environment, created on push, destroyed on merge.
Here's the claim: preview environments stopped being a luxury the moment scale-to-zero billing became real, and the remaining cost isn't infrastructure. It's engineering discipline, and most of that discipline is teardown. This post shows the arithmetic and the machinery, including the parts that bite, because "cheap previews" sounds like marketing until you can check the meter yourself.
Where "around three cents" comes from
A preview on our platform is a container that scales to zero. It bills nothing while idle, and idle is most of its life. The representative preview below assumes fifteen minutes of cumulative active traffic across its entire existence, one vCPU, 512 MiB of memory, and public Cloud Run list prices in a standard region as of August 2026.
| Line item | List rate | This preview uses | Cost |
|---|---|---|---|
| CPU | $0.000024 / vCPU-second | 900 vCPU-seconds | $0.0216 |
| Memory | $0.0000025 / GiB-second | 450 GiB-seconds | $0.0011 |
| Requests | $0.40 / million | ~10,000 requests | $0.0040 |
| Total | ~$0.027 |
List rates from the public Cloud Run pricing page, standard region, request-based billing, as of August 2026.
Call it three cents. The free tier (the first 180,000 vCPU-seconds each month cost nothing) would shrink it further, and a build minute plus image storage adds a little back; the order of magnitude doesn't move. Fifteen active minutes is generous, by the way. In my experience a preview gets opened about twice: once by the author confirming it deployed, once by the reviewer forming an opinion.
That observation carries the whole economic argument. An environment billed by the second costs what it's actually used, and a preview is barely used, so a preview is barely billed. A staging server priced by the month inverts this, charging you for every hour nobody is looking at it, which is nearly all of them. Same compute. Different pricing physics.
The table also hides a floor worth naming: with request-based billing the instance is only allocated while serving traffic, so a preview's eleventh day of existence costs exactly what its first did, which is zero if nobody visits. Longevity is free. Only attention is billed.
The lifecycle, and where it bites
open PR -> build image -> deploy revision -> post URL on the PR
push new commit -> rebuild -> replace revision (same URL)
no traffic -> scale to zero
merge or close -> destroy revision, DNS record, preview database
The first three lines are the demo. The fourth line is the product. Provisioning is a mostly solved problem with good primitives underneath it; teardown is where preview systems rot, because teardown's failure mode is silent. A missed webhook, a PR closed mid-deploy, a force-pushed branch rename: each one orphans an environment that sits invisible until someone finds it months later, still holding a database. So we treat reconciliation as the core loop, continuously comparing what should exist (open PRs) against what does exist (running previews), instead of trusting that every event arrived exactly once. Event-driven teardown is a rumor. Reconciliation is a fact.
Routing has a trap of its own. Every preview needs a working URL moments after push, and issuing a fresh TLS certificate per preview walks straight into Let's Encrypt rate limits on a busy repository, so previews live under a wildcard certificate and a wildcard DNS record provisioned once. One early decision deletes an entire class of flaky waiting.
Isolation is the second bite. A preview executes branch code, and branch code hasn't passed review yet, so a preview that receives production secrets is a phishing kit you built for yourself. Preview environments get their own scoped credentials and their own data, never production's, and that rule costs us real convenience, because "test it against real data" is the most requested thing previews can't safely be.
Databases are the third bite, and the honest one. Stateless containers scale to zero gracefully; PostgreSQL does not, and the trade-off triangle is real: a schema-only database is cheap and safe but empty, seeded fixtures are useful but drift from reality, and a copy of production data is realistic and a compliance incident waiting for a fork. Our default sits at the cheap, safe end of that triangle, and one rule is absolute: production data never crosses into a preview.
"That's not staging"
The strongest objection deserves its space: a preview with a seeded database won't catch the bug that only appears at production data shapes, won't carry a load test, and mocks the third-party integrations that break in the interesting ways. All true. A team that replaces capacity planning with preview environments will meet reality on a bad day.
But that objection compares instruments doing different jobs. Staging answers "does this survive production conditions"; a preview answers "is this the change we think it is", and it answers inside the review conversation, while opinions are still cheap to change. The expensive failure previews prevent isn't an outage. It's the LGTM that nobody actually looked at.
Around three cents buys a second opinion that loads in a browser. Next time someone says disposable environments are too expensive for your team, ask to see their arithmetic next to this table. Then ask what the last staging-slot conflict cost in engineer-hours, and compare columns.
Related: Cloud Pricing That Makes Sense, the pricing philosophy these previews are built on. More about what we're building at light-cloud.com.