The Boring Stack
A solution architect spends forty-five minutes walking me through a vector database. It deduplicates. It tiers. It scales horizontally to a billion embeddings. It has a friendly mascot and a Series B led by a fund I’ve heard of.
I ask, at the end, how many embeddings his client actually has, today.
Two hundred thousand.
I write down two words in my notebook: SQLite. Done.
He looks at me as if I had insulted the mascot.
A glossary entry
I want to start by defending the word.
Boring, in this context, is a compliment. It does not mean lazy. It does not mean unambitious. It does not mean stuck in 2008. It means the tool is well-understood, widely deployed, slow to change, and unlikely to surprise you on a Sunday night.
A boring stack is one in which most of the unknowns have already been someone else’s bug report.
Twenty-five years in, this is what I have come to prefer. Not because the new things are bad (many are not), but because the relationship between novelty and the work I have to do shifts as the years stack up. A junior engineer can afford to learn a new framework every quarter. A fractional CIO at a thirty-person SME does not have that quarterly budget to spend on tooling that has not yet stopped surprising people.
The cost of novelty is not the cost of the tool. It is the cost of the surprises the tool has not yet finished generating.
The three pillars
The boring stack I keep coming back to has three pillars. They are not the only choices. They are the choices I have stopped second-guessing.
SQLite. A single file, on disk, that fifteen years of production traffic have not managed to corrupt. The transactions are ACID. The schema is your schema. There is no daemon to keep running, no port to forward, no replication topology to debate at three in the morning. For most of the small-application workloads I see in fractional-CIO mandates, SQLite is the right answer and “we picked Postgres for future scale” is the wrong one, because the future scale never arrives and the team pays for the assumption every day until it doesn’t.
Markdown files. The CMS the team will never have to migrate. The blog post that opens in any text editor from 1995 to whatever editor exists in 2035. The contract that survives the SaaS that signed it. A folder of .md files versioned in git is not a content strategy; it is a content guarantee. The interesting day is the day you discover that someone is reading your 2014 notes with no special tooling.
Python standard library. The unfashionable claim that you almost never need the dependency. json parses JSON. sqlite3 opens the database. http.server serves files. smtplib sends mail. csv reads the spreadsheet. subprocess calls the binary. pathlib walks the disk. email writes the message. A working tool can be a single .py file that imports nothing that was not shipped with the interpreter, and that file will still run, unchanged, when the next four PyPI packages it could have used have been deprecated, renamed, or absorbed into a company that pivoted.
None of these is impressive. All three are still working in places I touched a decade ago.
What an old hand stops noticing
Dan McKinley, in 2015, gave the genre a name with Choose Boring Technology. His central image is the innovation token: a small, fixed budget of “interesting” decisions a project can absorb before it starts paying interest. Spend a token on a new database, a new language, a new orchestration layer, and the meter starts running. Spend them all in the same quarter and you have built a system whose moving parts nobody on the team understands.
The diagnosis aged well. What experience adds, on top of it, is a different sensitivity. After a certain number of cycles, you stop noticing the new things in the way you used to.
A junior engineer reads about a new vector database and feels the pull of let me try this. I read about the same database and feel, mostly, the absence of a question I had been asking. Most of what is announced this quarter is not solving a problem the systems I run actually have. The pull of novelty, for me, has been replaced by a quieter test: does this thing remove a recurring cost I am paying today?
If it does, I look. If it doesn’t, I move on. The rate at which the answer is no has climbed steeply over twenty years. Not because the tools are worse. Because I am paying fewer costs that they could remove.
What the impressive thing actually costs
The new tool does not cost zero. It costs:
- The week to read the docs properly, instead of skimming.
- The first six weeks of finding the edges nobody has written down yet.
- The hiring filter: you can now only hire people who know this stack, or who are willing to learn it on your dime.
- The vendor risk if the project is venture-funded and pivots in eighteen months.
- The audit risk if it crosses GDPR, sovereignty, or supply-chain lines that the boring tool had already cleared.
- The day, two years later, when the company that maintained it gets acquired and the roadmap quietly changes.
Each of these is small in the moment. The aggregate is a tax you pay until you cut the dependency. In an SME, that tax usually outlives the original problem the tool was meant to solve.
The boring tool has paid all those costs already, twenty years ago, in someone else’s project. That is most of what the word boring is doing in this manifesto.
When boring is the wrong answer
This is not a dogma.
There are problems for which SQLite is the wrong answer. There are content systems for which Markdown files are too thin. There are operations for which a Python script will never be enough.
The discipline is not always pick boring. The discipline is pick boring by default, and earn the deviation.
When a client tells me they need a real-time streaming database with sub-millisecond writes across three continents, I do not reach for SQLite. I ask whether the streaming, the millisecond, and the three continents are each loaded with actual evidence, or whether they are inherited from a deck. Often two of the three vanish under questioning. Sometimes all three are real, and then we go pick the right specialised tool, knowing the budget we are spending.
The point of the manifesto is to invert the default. Most teams reach for the impressive thing and have to justify the boring one. That asymmetry is backwards. The boring tool is the path that has already been walked. The impressive one needs to make its case.
The Sunday-night test
I have, over the years, developed one private heuristic for deciding.
When I evaluate a tool for a system I will be on the hook for, I ask: if this breaks at eleven on a Sunday night, what will I do?
For SQLite: open the file with any sqlite client, read the rows, fix the row, save. For Markdown: open the file in any editor, fix the typo, save. For a Python stdlib script: read the eighty lines, find the bug, edit, restart.
For the impressive thing: open three browser tabs to the vendor’s status page, the changelog, and the Discord, then wait.
Sunday-night ergonomics is the underrated metric. Most architecture decisions are made on Tuesday-afternoon energy and paid for on Sunday nights. The boring stack is unusually kind on Sunday nights.
The accumulating advantage
The asymmetry between boring and impressive compounds in a direction the early career does not notice.
In year one, the impressive choice is exciting and the boring choice is dull. Both work. The dev who took the impressive path has a more interesting story for the meetup.
In year five, the impressive choice has shipped a major version that broke a few assumptions. The boring choice has shipped a security patch and is otherwise unchanged. The boring path is starting to look quietly sensible.
In year fifteen, the impressive choice has been deprecated, forked, re-architected, or absorbed by a different company that no longer maintains it the same way. The boring choice is indistinguishable from year five. It has become a moat.
This is not a story about being right. It is a story about the asymmetry of being wrong. When the boring choice is wrong, you are wrong for a quarter and you change it. When the impressive choice is wrong, you are wrong for years, and you cannot unwind the decision without rewriting the system around it.
The bored CIO
What experience produces, in the end, is not better taste. It is calibrated boredom.
A twenty-five-year career filters every new tool through a slow question: what cost is this removing that I am paying right now? Most of the time, the honest answer is none. So most of the time, the choice is to do nothing new, and to use the same boring things that worked last quarter and the quarter before.
This is not stagnation. It is the highest-leverage move available, in any year I have practiced. The tools that have stayed boring for fifteen years are precisely the ones whose costs have been amortised over thousands of projects that are not mine to subsidise.
I close the laptop. The SQLite file is still answering queries. The Markdown notes are still where I left them. The Python script is still running. Nobody noticed me leaving.
That is the entire pitch.
Simplicity is prerequisite for reliability. — Edsger W. Dijkstra, EWD498, 1975