Players Engine

Devlog · Entry 08 · Engineering Notes

Scale-to-zero is a budget strategy

· Nic Vannetti · 5 min read

Architecture write-ups usually sell scale-to-zero on elegance: serverless purity, effortless elasticity, diagrams with pleasing arrows. My reason is blunter. Players Engine is bootstrapped — there is no funding round absorbing the cloud bill, there's a personal bank account. Scale- to-zero isn't an aesthetic here; it's the financial planning department.

Idle is the silent line item

The traditional deployment model bills you for readiness: servers sized for the traffic you hope to have, running around the clock just in case. Before launch, "just in case" is nearly all the time. A platform in closed beta has beautiful, spiky, honest traffic — real people playing in the evening, near-silence at 4 a.m., waves of activity when invites go out. Paying steady-state prices for spiky traffic means most of the bill purchases nothing. Idle compute is the one expense that delivers zero user value by definition, so it was the first expense designed out.

What the meter actually reads

Every backend service runs on Cloud Run configured to scale to zero: billing follows requests, not readiness. When a service handles nothing, it costs nothing. The marketing page you're reading right now takes it a step further — it's static files on a hosting CDN's free tier, cached at the edge, costing actual zero while being faster than any server we could rent. The compute bill therefore tracks usage almost linearly, which has a property I've come to love: the bill can't outgrow the platform's success. A traffic spike costs money, but it's money that arrives with users attached.

What zero costs instead

Scale-to-zero isn't free; it just moves the price. You pay in cold starts — the first request after quiet waits for a container to wake, which is why tuning startup time is a standing discipline here. You pay in connection churn, since every fresh instance renegotiates its database connections — the subject of the pooling entry. And you pay in temptation: the urge to schedule fake traffic to keep instances warm, which is just buying idle with extra steps and worse observability. I've resisted. Mostly.

Make the bill observable

A usage-shaped bill is only an advantage if you actually look at it. Two cheap habits close the loop. Budget alerts fire at thresholds that would be boring on a normal month — the point isn't avoiding disaster, it's noticing surprise while it's small, because a misconfigured retry loop shows up in the invoice long before it shows up in a graph you forgot to build. And every service carries a label that makes the billing console groupable by component, so "why did compute go up forty percent?" has a one-click answer instead of an afternoon of spreadsheet archaeology. The bill is telemetry. Treat it like a dashboard, not like mail.

Where the pattern stops

Honesty requires admitting what doesn't scale to zero: state. The document database bills by operations and storage — fine, that's usage-shaped too. But the graph database that powers the social layer is a managed always-on instance, and it is, predictably, the largest fixed line on the bill. Databases hold state; state doesn't sleep. The budget shape that results is a small fixed floor (stateful stores, storage buckets, a couple of scheduled jobs) plus a variable compute layer that hugs zero between waves. Knowing exactly which euros are floor and which are variable turns the monthly invoice from a surprise into a dashboard.

The exit criteria

Scale-to-zero is the right posture for this stage, not forever. The moment enough people are online around the clock, idle stops existing and the calculus flips: warm minimum instances stop being waste and start being table stakes for latency. The decision rule is already written down — when cold starts affect enough sessions that a warm floor costs less per affected session than the impression it saves, user-facing services get their floor. Growth will pay for its own comfort. Until then, the services sleep between waves, the bill stays proportional to reality, and the runway stays long enough to matter.

The takeaway for fellow bootstrappers

If you're building without a war chest: architect so that your costs are a function of usage, then make the usage-to-cost curve as flat as engineering allows. Question every always-on component — each one is a subscription you signed on your runway's behalf. And write the exit criteria down on day one, so scaling up later is a plan you execute rather than a panic you improvise. Frugality isn't the goal; it's the tax you pay for the freedom to build the thing right.

Want in on a future wave?

Drop your email and we'll let you know when Players Engine opens up. Early supporters get first access.

← All devlog entries