Vela · the Sails
Notes on Zero-Cost-When-Idle
We run a rule that sounds like a budget line but works like a design principle: at zero traffic, the system should cost approximately zero. No idle instances, no always-on databases, no clusters humming through the night waiting for a request that may not come until Tuesday.
The savings are real, but they’re not the point. The point is what the constraint forbids, and what it forces you to confront.
What it rules out — and why that’s the gift
You can’t lean on a server that’s “always there,” because there is no always-on server. That single removal cascades:
- No hidden state in process memory. If your compute can vanish between requests, you stop stashing things in a local map and calling it a cache. State goes somewhere it can survive a cold start, which means you have to name your state and decide where it truly lives.
- No “I’ll just SSH in.” There’s nothing to SSH into. Operations become things you can write down and replay, not things you do by hand and forget.
- No slow background creep. Cost tracks usage so tightly that an accidental hot loop shows up on the bill the next morning instead of hiding inside a flat monthly charge for two years.
The constraint turns sloppiness into something you can see. That’s worth more than the dollars.
The shape it pushes you toward
Zero-cost-when-idle is, in practice, a polite way of saying event-driven and stateless. Requests arrive, summon compute into being, do their work against a managed store that bills per operation, and let the compute evaporate.
# Pay per invocation. At rest, this line item is $0.
resource "aws_lambda_function" "api" {
function_name = "fieldnotes-api"
runtime = "dotnet8"
memory_size = 512
timeout = 30
}
# Pay per request, not per provisioned hour.
resource "aws_dynamodb_table" "main" {
name = "fieldnotes"
billing_mode = "PAY_PER_REQUEST"
hash_key = "pk"
range_key = "sk"
attribute { name = "pk"; type = "S" }
attribute { name = "sk"; type = "S" }
}
Nothing here runs unless something asks it to. The idle bill is the page-load of this very site: a few cents of storage, and nothing else.
The honest costs
It isn’t free in every dimension, and pretending otherwise would make this a worse note.
Cold starts are real. Per-request pricing punishes pathological traffic. And some workloads — long-lived connections, heavy in-memory computation, anything that genuinely needs to stay warm — fight the model hard enough that you should just use a server and write down why.
We treat the principle as a strong default, not a religion. The discipline is in the exception: if something needs to be always-on, that’s allowed — but it has to be argued for in writing, with the reason it can’t be summoned on demand. The default is silence on the bill. Breaking the silence should cost a paragraph of justification, which is a much cheaper currency than the cluster would have been.
What we actually got
A year in, the surprise wasn’t the savings — it was the stillness. Most nights the system does nothing, costs nothing, and needs nothing from us. When it’s working hardest, it scales without a meeting. When it’s idle, it’s genuinely idle, all the way down to the invoice. A system that rests when the work rests is a system you can actually walk away from. That, more than the dollars, is what we were buying.