Why I went back to a static site
Every dynamic blog I have run eventually broke in a way that had nothing to do with writing. Here is the case for plain files.

On this page
I have rebuilt this site more times than I have written posts for it, which is its own kind of confession. WordPress, then a Rails app, then a Next.js thing with a headless CMS. Each rebuild was justified at the time. None of them made me write more.
This post is plain .md rather than .mdx — no components, no imports. It is
here partly to make a point: most posts never need more than markdown gives
you, and the ceremony of the fancier format is optional.
The failure mode is always the same
A dynamic blog has a database, a runtime, and a deploy target that all need to be alive at the same moment somebody clicks a link. That is three things that can rot while you are not looking. Mine rotted in this order, reliably:
- A dependency picked up a breaking change in a minor release.
- The hosting provider changed its free tier.
- The CMS I was using got acquired.
None of that is about writing. All of it landed on a Saturday.
The database was the worst of it
The Rails version had eleven tables. Nine of them existed to model things a blog does not actually have: drafts with workflow states, a taxonomy with hierarchy I never used, a comment system with moderation queues that only ever held spam.
The database was not storing my writing. It was storing the accumulated weight of features I had built because they were easy to build.
The markdown files that replaced all of it are, collectively, smaller than the schema migration folder was.
Plain files don’t rot
A static build has one output: a directory of HTML, CSS and images. It can be served by anything — a CDN, an S3 bucket, a spare machine, or this, if it comes to that:
cd dist && python3 -m http.server 8000There is no runtime to patch and no database to migrate. If the build tool
disappears tomorrow, the dist/ folder still works, and the markdown is still
markdown.
The performance argument is the second-best one
It is real, though. There is no server round trip, no hydration, nothing to do but paint:
| What happens on a click | Dynamic blog | This site |
|---|---|---|
| Database query | yes | no |
| Template render | per request | at build |
| JS bundle to hydrate | 100–200 KB | ~0 KB |
| Time to first paint | 300–600 ms | 30–60 ms |
But speed is not why I moved. The best reason is that the thing survives my own neglect. A static site has no uptime to speak of because there is nothing running to fall over.1
What you give up
Being honest about the trade:
- Comments. Gone, unless you bolt on a third-party service — which puts you right back to depending on someone else’s runtime.
- Search, unless you precompute an index. That is what I do here; it ships as static files and runs in the browser.
- Anything genuinely personalised. A blog does not need it.
- Instant publishing. A post goes live when the build finishes, not the moment you hit save. In practice that is about ninety seconds.
That is a short list, and I would rather pay it than spend another Saturday upgrading a CMS so that a post from 2019 keeps rendering.
Would I recommend it
If you are writing for yourself and you are comfortable with a text editor and git: yes, without hesitation.
If you need non-technical people to publish without help, no — that is exactly the problem a CMS solves, and solving it yourself with a static site generator takes longer than you think. Pick the boring hosted thing and get on with it.
The point was never that static is objectively better. It is that I kept choosing tools that needed maintenance, and then resenting the maintenance.
Footnotes
-
Your host can still fall over, obviously. The difference is that recovering means copying a folder somewhere else, not restoring a database and hoping the schema still matches the code. ↩