Keeping a SaaS in the EU: what self-hosting answers, and what it does not
"Where is the data?" is the second question every European enterprise buyer asks, right after the price. If your answer requires a diagram with five vendors on it, the deal slows down. If it is one sentence, it does not.
This post separates what self-hosting actually settles from what you still have to do — because pretending a technical choice is compliance would be dishonest and would fail your first audit.
What self-hosting settles
Data residency. Choose a server in Frankfurt, Paris or Amsterdam and the database, the sessions, the uploaded files and the logs are there. No region-by-service map, no "the control plane is in us-east-1 but your data is not", no surprise when a vendor adds a processing region.
The sub-processor list. Every managed service in your stack is a processor you must name, contract with, and keep an eye on. A self-hosted binary has one entry: your hosting provider. If you also use a payment provider and an email relay — most products do — that is three, and each one is there for a reason you can explain in a sentence.
Transfer questions. No transfer outside the EU means no standard contractual clauses to attach, no transfer impact assessment to write, and nothing to redo when the legal ground shifts again.
Exit. You can move hosts in an afternoon: it is a binary, a database dump and a volume of files. Portability is a GDPR principle and, more practically, a negotiating position.
What self-hosting does not settle
Be clear-eyed here. Running your own server does not make you compliant.
- A privacy policy and a processing register are still yours to write.
- A legal basis for each processing purpose is still yours to establish.
- Data subject rights must work in practice: access, export, rectification, erasure — within a month, without heroics.
- Retention must be decided and enforced. "We keep everything forever" is not a policy, it is a liability.
- Security measures must be real and documented: encryption in transit, access control, logging, backups, incident response.
- A processor agreement with your host is still required, as is one with every other vendor you keep.
The honest framing: self-hosting removes an entire category of third-party questions and leaves the internal ones, which you would have had anyway.
What a boilerplate can do for you
Some of the above is code, and code can ship. In GoVueKit:
- Data export — a signed-in user downloads their data as JSON, which is the portability right implemented rather than promised.
- Account erasure — a real delete, with the sensible guard that the sole owner of a shared organization must transfer or delete it first; solo organizations are erased with the account.
- An audit log of administrative actions, including impersonation, which is exactly what an auditor asks to see.
- Session visibility and revocation — users list their signed-in devices and can end sessions, which covers a surprising number of questionnaire lines.
- Encryption in transit by default — the production compose file puts the
app behind Traefik with Let's Encrypt, and the reference Traefik stack ships
in
deploy/traefik/; there is no HTTP-only path to forget. - Security baseline as code — argon2id password hashing, CSRF on every state-changing route, strict CSP and security headers, an anti-SSRF outbound client, timing-safe token comparison. Each one is a line you can point at in a questionnaire and a test you can run.
- Error reporting you control — the reporter is an interface; if you would rather not send stack traces to a third party, do not configure one and nothing leaves the process.
What it cannot do is decide your retention periods or write your register.
The enterprise questionnaire, in practice
The document that arrives before a serious contract asks roughly this. A self-hosted deployment answers most of it structurally:
| Question | Self-hosted answer |
|---|---|
| Where is data stored? | Our server, region X. |
| List sub-processors. | Host, payment provider, email relay. |
| Is data encrypted in transit? | Yes, TLS terminated at our proxy. |
| Who can access production data? | Named administrators, over SSH keys. |
| How are passwords stored? | argon2id, 64 MiB, 3 iterations. |
| Is there MFA? | TOTP, on every sign-in path. |
| Are administrative actions logged? | Yes, audit log with actor and target. |
| How is data deleted on request? | Self-service erasure, plus backup expiry. |
| What is the backup policy? | Nightly, off-server, restore tested. |
| Can we get our data out? | JSON export; full database dump on request. |
The rows you must fill in yourself are retention periods, incident response times, and who your DPO is (if you need one). Everything else is a consequence of the architecture.
When EU self-hosting is not the right call
- Your users are global and latency-sensitive. One EU server serving Sydney is a bad experience; you will want a CDN in front, or regional deployments, and that is a different design.
- You have no operations capacity and no intention of acquiring any. A European managed platform is a better answer than an unpatched VPS. There are EU-based ones; residency does not require self-hosting.
- Your customers do not care. If you sell to US startups, this whole article is a rounding error next to shipping features.
Data residency is a sales advantage in some markets and irrelevant in others. Know which one you are in before you optimise for it.
The practical setup
If you decided EU residency matters:
- Host with a European provider (Hetzner, Scaleway, OVHcloud). Choose the region explicitly.
- Keep the processor list short and deliberate: payments and email are worth renting; identity and database are not.
- Turn on the product features that implement rights — export, erasure, session revocation — and test them like features, because they are.
- Write the register and the retention policy. Two documents, an afternoon, and they are what an auditor actually reads.
- Restore a backup. Availability is part of the security obligation, and an untested backup is not a backup.
See the security checklist on the product page or read what renting the stack commits you to.