There is no shortage of content management systems, so the burden is on me to say what is missing.

Two years of writing these has left me with a short list of things I believe, and no system that holds all of them at once.

Content should be files. Readable, diffable, greppable, in version control, still openable in fifteen years. The flat file people are right about this and have been for over a decade.

Files should not mean giving up querying. Filtering, sorting and paginating a few thousand documents should be a millisecond, not a directory walk. That means an index, and the index should be a cache: deletable, rebuildable, never the only copy of anything.

The model belongs in code. Reviewed, branched, deployed. Payload is right about this.

The body should be markup where markup is good and structure where it is not. Prose as Markdown because Markdown is good at prose. Galleries and embeds as data because Markdown cannot say them. Nobody quite commits to this and it seems obviously correct.

Nothing should be rendered by the CMS. The content outlives the site.

It should not need much. A CMS serving a few thousand documents should be measured in tens of megabytes, and it should be fast because it does little, not because four caches are in front of it.

Take those six seriously at once and the field thins out considerably. Kirby has the first and gives up the second past a certain size. Payload has the third and puts content in Postgres. Sanity has the fourth and stores everything in a proprietary document store. None of them has the last one, because they are all built on runtimes with a floor of a few hundred megabytes.

The other half of the argument is the runtime, and it comes from the performance piece I wrote in November. Most CMS slowness is bootstrap: rebuilding the world per request. OpenResty does not have that shape. Lua state persists in the worker between requests, so the configuration is parsed once at startup and every request after that starts with everything already in memory.

People use it to sit in front of applications. Almost nobody builds the application in it. The reasons are ecosystem rather than technical, and the ecosystem gap is smaller than it looks: SQLite, cmark and libyaml are all C libraries, and LuaJIT's FFI calls C without a binding layer.

So the plan is roughly: Markdown files as the truth, SQLite as a disposable index over them, OpenResty as the runtime, a REST API and nothing else, and an admin that is a separate application talking to the same API as everyone else.

I have called it LagomCMS. Lagom is Swedish for the right amount, and I intend to use it as a constraint rather than a slogan: when a feature can be argued either way, it stays out.

The next few of these are the work. What I take from which system, where those borrowings contradict each other, and what happens when I try to build it.