---
title: "Why I Prefer Boring Architecture"
description: "The pragmatic case for choosing proven tools over chasing new technology. This is not cowardice, it is a budget decision."
url: https://sade.dev/en/journal/why-boring-architecture/
lang: en
author: "Muhammet Şafak"
published: 2026-05-15
updated: 2026-09-06
section: Journal
tags: ["architecture","decisions","opinion"]
summary: "Every team has a fixed complexity budget — about three innovation tokens — and a boring stack is what is left after refusing to spend them on infrastructure. I spend mine on domain complexity, one new infrastructure piece a year, and one small experiment. A new tool needs 12 to 18 months in production before it counts as boring, and only a measured need buys an exception."
---

# Why I Prefer Boring Architecture

> Every team has a fixed complexity budget — about three innovation tokens — and a boring stack is what is left after refusing to spend them on infrastructure. I spend mine on domain complexity, one new infrastructure piece a year, and one small experiment. A new tool needs 12 to 18 months in production before it counts as boring, and only a measured need buys an exception.

When a junior engineer asks me "why are you bothering with Laravel, framework X is faster," I start a conversation with a sigh. The answer is not "Laravel is better because Y." The answer is this: **"Every team has a limited complexity budget, and I prefer to spend it somewhere more important."**

## What does "boring" mean?

Dan McKinley's famous "Choose Boring Technology" essay popularized the term. "Boring" here is not bad — it means **predictable**, **well-documented**, and **answerable, when something breaks, from a Stack Overflow post written a decade ago**.

For me, the boring stack is:

- PHP + Laravel or Symfony
- PostgreSQL
- Redis
- Nginx
- Linux + systemd + Supervisor

When I add a new one — say RabbitMQ — it takes 12–18 months of active production use before I'll move it into the boring category. Until then it's experimental, suspect.

## The "innovation token" idea

In the same essay McKinley uses a metaphor called the **innovation token**: every team has a limited number of tokens to spend on innovation. Choosing a new language is a token. Choosing a new DB is a token. A new deployment platform is a token.

For a typical small team the budget is: **3 tokens**.

When you spend them on:

- A new programming language
- A new type of database
- A new messaging system
- A new orchestration platform

you have no tokens left for the product itself — for the complexity that actually produces value.

## Where do I spend my three tokens?

On most projects I spend these three:

1. **Domain complexity.** Business rules, distributed workflows, eventual consistency — these eat budget because the work requires it.
2. **A new piece of infrastructure** (e.g. adding a message broker, adding a search engine). Once a year at most.
3. **A small slice of an interesting experiment** — building one feature with a new tool to see what we learn. Most of the time it gets thrown away.

Everything else is **proven**.

## A first-world problem?

No. The case for boring tech matters most precisely **when our resources are limited**. When big companies say "we're moving all our flows to GraphQL," some fraction of 200 engineers is working on it. Your 3-person team doing the same = 3 months of not building features.

## "But this infrastructure is old"

PostgreSQL has been around since 1996. PHP since 1995. Nginx since 2004. Redis since 2009.

"Old" is not the right word — **mature** is. Mature software:

- Has its edge cases discovered and fixed.
- Gives error messages that return an answer when you Google them.
- Lets a new team member be productive on their first day.
- Doesn't make "who created this bug" trace back to your library version.

## Where are my exceptions?

1. **When a feature can't be built with a proven tool.** Example: CRDTs (Conflict-free Replicated Data Types) for real-time collaborative editing — this isn't a mature space, and you don't want to write it from scratch.
2. **When everyone on the team is experienced with the new tool.** If 5 engineers have been writing Go for years, forcing them onto PHP is wrong.
3. **When the performance requirement is clear and measured.** Not the hypothesis "it'll be faster," but the demonstration "there's a bottleneck here, language X solves it."

## Conclusion

Building new technology is exciting. **Running** old technology is boring. The difference between those two is the difference between a 2-year-old product in production and a 6-month-old one. Choose based on whichever side you care about — but make the choice knowingly.

Boring tech is not cowardice, it's a budget decision. Spend your budget on more valuable problems.

## Frequently asked

**What does boring technology actually mean?**

Predictable, well documented, and answerable from a decade-old Stack Overflow post when it breaks. Old is not the right word — mature is: the edge cases are already found, the error messages return an answer when you search them, and a new team member is productive on day one. A tool joins that category after 12 to 18 months of active production use, not on the day I install it.

**Where should a small team spend its innovation budget?**

On domain complexity, on at most one new piece of infrastructure a year, and on a small experiment that usually gets thrown away. Spend the budget on a new language, a new type of database, a new messaging system and a new orchestration platform instead, and nothing is left for the complexity that actually produces value.

**When is choosing a new technology justified?**

In three cases. When the feature genuinely cannot be built with a proven tool, such as CRDTs for real-time collaborative editing. When everyone on the team is already experienced with the new tool. And when the performance requirement is measured rather than assumed — a demonstrated bottleneck, not the hypothesis that it will be faster.


## Sources

- [Choose Boring Technology](https://mcfunley.com/choose-boring-technology) — Dan McKinley
- [A Brief History of PostgreSQL](https://www.postgresql.org/docs/current/history.html) — PostgreSQL
- [nginx CHANGES: 0.1.0, the first public version (04 Oct 2004)](https://nginx.org/en/CHANGES) — nginx
