Blog

/

Where your email data lives, and what it means for lock-in

The word “self-hosted” gets stretched to mean almost anything, so let’s skip the label and ask the specific question: where do the messages live, who can read them, and what does it take to walk away. This post is about the data boundary Flowmails draws around your domain’s mail — where it is stored, how it is scoped, and how completely you can take it with you.

What “self-hosted” usually means

In most email platforms, “self-hosted” is a marketing claim. The product is open source, the binary runs on your machine, and yet the database schema, the migration tooling, and the upgrade path are all owned by the vendor. If you want to leave, you discover what was actually yours on day one and what was rented back to you.

For email data specifically, the only thing that really matters is the database. Anyone can ship a UI. The hard part — the part that determines whether you can actually leave — is where the rows live.

One store, one boundary, scoped to your domain

On Flowmails, your mail lives in a store the platform operates: a serverless SQLite database for messages, routes, and keys, object storage for attachments, and a key-value namespace for the route tables. That is the honest answer, and it is worth saying plainly — the rows are not sitting in a database you administer yourself.

What makes that different from a locked-in store is the boundary around it. Every row carries your domain_id, every query the platform runs is scoped to one domain, and every credential — an API key, a route table, an outbound provider configuration — belongs to exactly one domain and cannot see another tenant’s data. Inbound mail for your domain arrives at a routing address of the form rec_{domain_id}@flowmails.net, so the tenant boundary is visible in the routing path itself, not just in a query filter.

That boundary is documented rather than implied. The API shape is public and stable, the message endpoints expose the same data the inbox shows, and there is no proprietary format to unpack.

What this changes in practice

Compliance reviews get shorter. When a security reviewer asks where customer email data is stored, the answer is a named boundary rather than a vague “our infrastructure”: a platform-operated store, one domain scope per tenant, and documented access paths. There is no shared multi-tenant table where your rows sit next to another customer’s.

Exit cost is approximately zero. The message API exposes the same data the inbox shows, so a one-off script can export a domain’s mail — messages, attachments, routing rules — and hand it to whichever vendor you move to next. Nothing has to be reverse-engineered, and no migration tool has to be bought.

AI features stay inside the boundary. With the AI draft-and-reply feature in preview, the messages used as context and the resulting drafts live in the same domain-scoped store as everything else. Inference can run on Workers AI by default, and the context drawn from one domain’s mail is never mixed with another tenant’s.

The trade-offs nobody will hand to you

The underlying store is serverless SQLite, not Postgres. You do not get row-level triggers, full-text search extensions, or arbitrary stored procedures. For most email workloads, that is fine — the shape of the data is simple and the access pattern is read-heavy with a few writes.

The other honest trade-off is that you are a tenant of a managed platform, not the operator of a database. You do not get a console to poke at, and you cannot run SQL against the store yourself. What you get instead is a dashboard for the human workflow, a REST API for the service workflow, and an export path that works without our help.

Know exactly where your email data lives — and how to take it with you.

Start free