One process. Many websites. A database each.
Every domain is a full site: its own SQLite files, templates, users, admin and agent endpoint. No container, no runtime, no database server per site. A new one is a folder, a line in the config and a reload.
For people who run sites for a living — agencies, hosting and white-label platforms, and anyone building a factory of sites an agent maintains.
one binarya site per domainSQLite per siteagent-managed
Instead of a classic CMS
a CMS on a language runtime, a database server and a proxy
Their trade. Everything is ready — and you run the stack that carries it, plus a plugin tree to patch forever. That tree is where the breaches come from, and the per-request hook assembly is why the first plugin everyone installs is a cache.
Ours. One binary. No runtime, no database server, no proxy, no plugin API — that whole class of hole is absent. What remains is the engine itself: templates, uploads, admin, TLS, config parser. One codebase to trust, updated by replacing one file. Sign-in uses OPAQUE: the password never reaches the server, no hash is stored, so a stolen database has no hash dump to attack.
The admin comes from the same config. A menu item points at a view, a form lists fields,
templates live in your hbs/. Add a column — it is in the admin. Restyle it like any page,
because it is one.
When they are better. You need a plugin that already exists — a shop with payments and logistics, a marketplace integration — or thousands of ready themes.
You no longer need a static generator to get static speed
a generator, plus a form service, a headless editor and a CDN
Their trade. A file on disk beats a page assembled per request — at the cost of the site being alive. Forms, editing and anything dynamic move to other services; every change costs a rebuild. In return you get atomic releases and a Git history.
What changed. A hot page here is rendered once, compressed once and served from memory. Against a hand-tuned static file server on the same bytes, the difference is noise. Static throughput, live site.
Start static, grow later. Admin, auth, forms, uploads, API and the agent endpoint are config sections: a site that omits them registers no such routes. Serve pages from memory today, add a form when you need one, an admin when someone edits, an agent when you want one. The deployment never changes.
The rest transfers too. A CDN in front gives the same edge delivery on cacheable pages, and a fast origin makes a miss cheap — purge aggressively instead of nursing long TTLs. Publish atomically: prepare a folder, switch the config, reload. Keep templates and config in Git. Scale reads through the edge or read-only replicas.
When they are better. Git-only editing is the workflow you want, or running no origin at all matters more than forms and an editor. A real preference — no longer a performance one.
Instead of a BaaS or headless backend
a database with an API and an admin; the website is on you
Their trade. You get data, auth and an admin over that data. The site is still yours to build: a frontend, its tooling, its hosting, and the glue between the two. Two systems, two update cycles, two places to break.
Ours. The API is here — any view is JSON on a path you choose — and so is the site: pages rendered from the same views, forms writing to the same tables, media, admin, TLS. One process, one config, one backup. Want a separate frontend later? The JSON is already there.
When they are better. Your product is an app, not a site — a mobile client, a dashboard, a rich SPA — and the backend should stay out of the way.
And three more, briefly
| instead of | their trade | ours |
|---|---|---|
| a hosted builder | simplicity, rented: you pay per editor and per feature, and the site lives inside the platform | the same "it just runs" — HTTPS renewed by the binary, admin included — but the site is a folder you can move. Editors are free; you pay for the VPS |
| a web framework | write the application, then maintain it and its dependency tree for the life of the site | the recurring parts are configured, not coded. Dependencies ship inside the binary; no build, no code of yours to audit |
| shared hosting or a container per site | shared neighbours share a runtime; containers isolate but cost an image, a database and an update cycle each | one process, a site per domain, each with its own data, users, templates and token. The process is shared — an engine flaw is an engine flaw — nothing else is |
The trades side by side
| what you write | what you operate | whose data | who runs the site | |
|---|---|---|---|---|
| Classic CMS | settings + plugins | runtime, DB server, proxy, plugins | yours | humans in an editor |
| Static + services | templates + markdown | a build pipeline and each service | yours and the services' | humans with Git |
| BaaS / headless | a whole frontend | backend + frontend hosting | yours | developers |
| Hosted builder | nothing | nothing — and nothing moves out easily | yours, inside their platform | humans in a browser |
| Framework | the application | app, DB, proxy, dependencies | yours | developers |
| CMSnap | a settings.json and templates | one binary | yours, in a folder | humans — or an agent over MCP |
What "agent-managed" means
The MCP endpoint is not an integration bolted onto a CMS — it is the admin panel for agents. The handshake itself teaches the workflow: connect any MCP client and the server answers with working instructions, and the full site grammar — tables, views, routes, forms, templates — ships as an MCP resource the agent reads on the spot. No SDK, no plugin, no separate frontend project: one endpoint covers content, schema, routes, templates, CSS/JS, media and the admin screens themselves.
A site can hand an agent its own token. With it the agent reads and writes that site's content, uploads
media, edits its templates and settings — an administrator's reach over the site's content, not over its
accounts. Every change passes the same gate as a human's: check refuses a structurally
broken candidate, an atomic reload applies a valid one — the running site never serves a half-written
config.
What the token cannot do is the point. No tools for users or passwords. No server operations. The endpoint answers only its own domain, so a token never opens a neighbour. Pin it to IP addresses, revoke it in one click, read every call in the request log. The server-scope token is a different order of trust: it creates and removes sites — hand it over only when you mean "run my whole node".
Numbers, not adjectives
Each claim is measured — hardware, CPU pinning and load settings next to the result — and reproducible with one public script:
- Cached page: a million requests per second on 16 server cores, at a 175 µs median — static-file-server throughput from a live engine.
- Page from the database: a SQLite read and a render per request — 255,000 req/s across a hundred sites, cache off.
- Density: 10,000 full sites — a database, an admin and keys each — cost five percent of throughput.
- Writes: ~200,000 committed inserts per second into one database, 495,000 across a hundred — a database per site turns isolation into write parallelism.
- Cost: each additional benchmark site used ~8 MB of RAM; on a benchmark-class cloud VM (32 vCPU / 128 GB, $704–1,354 — US public clouds, Aug 2026) that is 7–14 cents per site per month of compute, before traffic and redundancy — a bill that grows in server-sized steps, not per site.
Where this comes from
CMSnap grew out of sqliteonline.com — SQL in the browser since 2014. More than a decade of operating that service — its load, its edge cases, its failure modes — went into this engine. Its console is that same workbench, pointed at your node.