Why boring infrastructure wins
The systems that survive don’t win because they were clever. They win because someone made the unglamorous decisions — the ones that don’t make conference talks — and stuck with them.
The first of those decisions is how you deploy. Most teams overthink it, copy whatever architecture diagram was on stage last, and end up paying for elasticity they’ll never use or scrambling for capacity they should have planned. The honest answer is almost always one of two shapes.
One server, done well
If your traffic is steady and predictable, a single server with Kamal is hard to beat. One box, Docker containers, a reverse proxy terminating TLS, deploys that take a minute. You own the whole thing, you can reason about the whole thing, and there’s almost nothing in the middle to break.
This is the setup people are embarrassed to admit they run — right up until they notice it’s been up for a year, costs less than a team lunch per month, and has never paged anyone at 3am. Boring. Load-bearing.
Many containers, when the load demands it
When traffic is spiky or genuinely unpredictable — launches, seasonal peaks, workloads that go from idle to flooded in minutes — you want something that scales horizontally without you babysitting servers. ECS Fargate with multiple containers behind a load balancer does this well: containers come and go with demand, you don’t manage hosts, and you pay closer to what you actually use.
It costs more and there are more moving parts. That’s the trade. You take it on when the traffic shape demands it — not because it looks more serious on a diagram.
The rule is simple: match the deployment to the traffic, not to the architecture you admired at a conference. Most products are the first case for years. Some genuinely need the second. Knowing which one you are is the whole skill.
Nothing sits naked on the internet
Whichever shape you pick, the service does not face the open internet bare. The moment something has a public address, it gets traffic you never asked for — bots, scanners, scrapers, the constant background noise of the web. You need a layer that absorbs the unintentional traffic before it reaches anything that matters.
Two allies do most of the work:
- Cloudflare in front of everything: DNS, TLS, a WAF, rate limiting, bot mitigation, and caching. It soaks up the junk at the edge so it never touches your origin, and it turns a single exposed box into something that quietly shrugs off the noise.
- AWS for the inside: private subnets, security groups, least-privilege IAM, and Shield/WAF where it earns its keep. The goal is a small blast radius — if something does get through, it can’t reach much.
Neither is glamorous. Both are the difference between an incident and a non-event.
That’s the pattern, all the way down: the impressive decisions get the talks; the boring ones keep the system alive. Pay for the boring ones early.