Most of us ship software the same way now. Pick a framework, pull in a few hundred dependencies, and the service idles at a gigabyte of RAM before it does its first useful piece of work. Nobody profiles it. If it’s slow, you scale up. Compute is cheap, your time isn’t, and the bill goes to someone else. I don’t say that as a complaint. I’ve done it, and I’ll do it again on the next deadline.
I used to live in a different world. I’d spend hours, sometimes whole weekends, squeezing a program onto hardware that “couldn’t possibly” run it. Getting it to run anyway was the best feeling I knew. The demoscene was my inspiration. I’d watch an intro do impossible things in 64 kilobytes and sit there asking myself how on earth they’d done that.
That instinct feels quaint now, and I know it. But I think we lost something when we stopped caring, and the cost of losing it has started showing up on the electricity meter.
Where I learned to count bytes
In the scene, the constraints were the whole point. A 64KB intro had to carry its own graphics, music and animation, most of it generated at runtime because there was no room to store any of it. Every byte was a decision somebody had made.
Groups like Future Crew, Farbrausch and Conspiracy turned that limit into art. .kkrieger is the one I still bring up. A complete first-person shooter, with textures and levels and enemies, in 96KB. A single modern web font is bigger than that.
Was it masochism? A bit. But mostly it was craft. You had to understand the hardware well enough to get performance out of it the spec sheet said wasn’t there. That is the same understanding I still value most in the work I do now. When you know why something is fast, you know why it breaks.
How we stopped
Then the ground shifted.
Cloud made infinite scale a checkout button. Moore’s Law kept paying out. Storage went from precious to free. And the habit of optimising drained away, because the economics stopped rewarding it.
Why spend three days tightening an algorithm when a bigger instance costs less than your afternoon? Why compress assets when bandwidth is metered in fractions of a cent? Why profile anything when the customer can buy more RAM? Every one of those questions has a defensible answer. I’ve given the lazy one plenty of times myself.
Here’s what that looks like in the enterprise environments I’ve worked in:
- Applications that need 32GB of RAM to display a spreadsheet
- Docker images measured in gigabytes for services that do almost nothing
- JavaScript bundles that take longer to parse than the interaction they enable
- “Microservices” that demand more resources than the monolith they replaced
At some point we decided, without ever voting on it, that developer time is expensive and compute is cheap. So we spend the compute to save the time. That was a fair trade when the only thing at stake was a cloud bill. I’m less sure it still is.
The bill that doesn’t come in the post
Every CPU cycle you don’t need still burns electricity. A bloated image still needs a disk to sit on and a network to move across. An over-provisioned Kubernetes cluster draws power around the clock to keep idle cores warm.
Data centres already use somewhere around 1 to 2 percent of the world’s electricity, and that figure is climbing fast now that AI workloads have arrived on top. When your inefficient code runs on one laptop, nobody notices. When it runs on ten thousand instances, the waste runs on ten thousand instances too. At that scale the gap between O(n) and O(n²) stops being a whiteboard exercise. It turns into kilowatt-hours, and further up the chain into generation capacity and carbon.
This is the part I keep coming back to. We’ve treated compute as disposable. Take what you need, scale on demand, never look at the waste. That worked as long as the second bill never arrived, and it’s starting to arrive.
What a demoscener would do with a cluster
Most of the old mindset survives the jump from 64KB intros to production systems. I’ve ended up with four habits from it.
Measure first. Demosceners never guessed at what was slow. They profiled until they knew. We have better observability tooling than they could have dreamed of, and we mostly point it at debugging instead of efficiency. The data is already there.
Question the default. Does this service need 2GB of base memory, or did it ship with that number and nobody ever checked? Does this JSON response need every field? Does this cron job need to run every minute? Usually the answer is “no idea, it’s always been like that”.
Treat the constraint as a feature. Give yourself a 50MB image limit. Force a service to run in 256MB. I’ve watched limits like that produce cleaner designs, the same way 64KB forced the scene to invent procedural generation because nothing else would fit.
Make efficiency visible. In the scene, small and fast earned respect. In most companies it’s invisible work that never makes the sprint review demo. We celebrate the feature. We could just as well celebrate the engineer who halved the cluster footprint.
What you can start this week
I’m not suggesting you write a demo. But several habits from that world map straight onto how we run infrastructure, and none of them need a budget.
Profile before you scale. Before you reach for a bigger instance, find out why the current one is struggling. In my experience it’s one bad database query or a slow memory leak, and the fix is cheaper than the upgrade.
Right-size everything. Kubernetes resource requests and limits decide how many cores sit idle and warm. Set them from what the service measures, because the values it shipped with were a guess.
Measure energy directly. Scaphandre, Kepler and Cloud Carbon Footprint show the actual energy draw of your workloads. Most teams have never looked at it once.
Schedule with the grid in mind. Run batch jobs off-peak, or when the grid is greener. Some providers offer carbon-aware scheduling out of the box now, and it costs nothing to turn on.
Cache aggressively. A computation you never run draws zero watts. Caching pays you back in latency and in electricity at the same time.
Pick the language for the job. Rust and Go burn far less energy than Python or Ruby for the same work. That doesn’t matter for a script that runs once a day. At scale it does.
Why it hasn’t happened yet
I know why I haven’t done all of this on every service I run. The incentives point the other way. Optimisation is real engineering effort with no demo at the end, and most roadmaps reward the new feature over the leaner one. A cloud bill is a number a CFO understands. A carbon footprint mostly isn’t, yet.
I’ve shipped the bloated thing on a deadline too. None of this is a moral failing. It’s a default we drifted into because every individual shortcut was rational at the time.
One service
If I had to point at where to begin, it’d be one service nobody would miss if it wobbled. Profile it, cut its requests to what it measures, put an energy meter next to it and see what the number does.
The demoscene showed that a hard limit makes you inventive. That was true when the limit was a 64KB file. It’s true again now that the limit is the grid, and I’d rather relearn it from the scene than from the meter.
The demoscene is now UNESCO-recognized cultural heritage in several countries.
