DEV Community

Cover image for What It Actually Costs to Run a SaaS on EU Infrastructure
Alex Neamtu
Alex Neamtu

Posted on • Originally published at sendrec.eu

What It Actually Costs to Run a SaaS on EU Infrastructure

The $6/Month Production Stack

There's a default assumption in the startup world that running production infrastructure means AWS, and AWS means expensive. We decided to challenge that assumption when building SendRec, an open-source async video platform, and the results surprised even us.

Our entire production stack — serving real users, handling video uploads, running email campaigns, collecting privacy-friendly analytics — costs $6.04/month.

Not a staging environment. Not a proof of concept. Production.

The Hardware

Everything runs on a single Hetzner CX33: 4 shared vCPU, 8 GB RAM, 80 GB disk. That's it. One server in Helsinki, Finland.

Hetzner is a German hosting company founded in 1997. They run their own data centers in Germany and Finland. No US parent company, no CLOUD Act exposure, no complicated jurisdictional analysis needed.

The CX33 costs EUR 5.69/month (about $6.04 USD at the time of writing). For context, the closest AWS equivalent — an EC2 t3.large in eu-central-1 — runs about $61/month. That's roughly 10x the cost for comparable specs. And if you start adding managed services (RDS, S3, SES, CloudFront), you're easily past $100/month before you've served a single user.

What's Running on It

We run 10 Docker containers managed by a single docker-compose.yml:

Service Purpose
Caddy Reverse proxy, automatic HTTPS, serves landing page
SendRec App Go backend + embedded React SPA
MinIO S3-compatible object storage for video files
PostgreSQL (x2) Production DB + staging DB
Listmonk Self-hosted newsletter/email campaigns
Listmonk DB PostgreSQL for Listmonk
Umami Privacy-friendly, self-hosted analytics
Umami DB PostgreSQL for Umami
Staging App Staging environment for the app

Yes, that's five PostgreSQL instances. Each service gets its own database for clean isolation. On 8 GB of RAM this is perfectly comfortable — each Postgres instance with a light workload uses very little memory.

The Supporting Cast

A few other services round out the stack, all chosen for EU alignment and cost:

Cloudflare — DNS only, free tier. We don't use their proxy or CDN. DNS resolution is fast and reliable, and the free plan does everything we need. Cloudflare is a US company, but for DNS-only (no data proxying), the jurisdictional exposure is minimal.

Brevo — Transactional email relay. Brevo (formerly Sendinblue) is a French company. Their free tier covers 300 emails/day, which is more than enough for account verification and password resets at our current scale.

BunnyCDN (planned) — For future video delivery optimization. Bunny is a Slovenian company with EU-based infrastructure. When we need a CDN for video streaming performance, they're the obvious choice.

GitHub — Source code and CI/CD. Yes, GitHub is Microsoft-owned and US-based. We accept this trade-off because the source code is public anyway (AGPLv3), and GitHub Actions handles our deploy pipeline. If this ever becomes a concern, Forgejo or Gitea on our own server is a straightforward migration.

The Deploy Pipeline

No Kubernetes. No Terraform. No Helm charts. No service mesh.

Deployments are handled by GitHub Actions calling a bash script on the server over SSH:

  1. PR opened — builds a preview environment at pr-{N}.app.sendrec.eu
  2. Merge to main — deploys to staging.app.sendrec.eu
  3. Push a git tag — deploys to app.sendrec.eu (requires manual approval)

The deploy script pulls the new Docker image, runs migrations, and restarts the container. It takes about 30 seconds. Caddy handles TLS certificates automatically via Let's Encrypt. Wildcard DNS on *.app.sendrec.eu means preview environments work without any DNS configuration per PR.

Total deploy infrastructure cost: $0. GitHub Actions free tier covers everything.

Why Not AWS?

It's not just about cost, though 10x savings is hard to ignore. There are several reasons we chose this path:

Simplicity. One server, one compose file, SSH access. When something goes wrong at 2 AM, there's exactly one place to look. No CloudWatch dashboards, no IAM permission debugging, no mysterious ECS task failures.

EU data sovereignty. Hetzner is a German company operating German data centers. There's no ambiguity about jurisdiction, no legal analysis needed, no DPA negotiations with a US cloud provider.

Predictable costs. EUR 5.69/month. Every month. No surprise bills because someone left a load balancer running, no data transfer charges that scale unpredictably with traffic.

It's enough. A single CX33 can handle meaningful traffic. We're not building for millions of concurrent users on day one. When we need to scale, Hetzner offers larger instances and dedicated servers. Vertical scaling is underrated.

The "But Does It Scale?" Question

Let's address it directly: no, this setup doesn't scale to Netflix levels. That's not the point.

For an early-stage SaaS serving hundreds or even low thousands of users, a single well-configured server is more than sufficient. The Go backend is efficient. MinIO handles object storage well. PostgreSQL is PostgreSQL — it'll handle far more than most people think before you need to worry about scaling.

When we outgrow this server, the path is clear: move to a larger Hetzner instance, or split services across multiple servers. Docker Compose makes this straightforward. The architecture doesn't need to change — just the hardware underneath it.

The startup graveyard is full of companies that over-engineered their infrastructure for scale they never reached. We'd rather spend $6/month and invest the savings in building a better product.

Advice for Fellow Founders

If you're starting a SaaS and reflexively reaching for AWS, pause for a moment. Ask yourself:

  • What do you actually need right now?
  • How many users are you realistically serving in the next 6 months?
  • Could a single server handle that load?
  • What's your actual compliance situation — do you need EU data residency?

For a lot of early-stage products, the answer is: a Hetzner VPS, Docker Compose, and Caddy will get you to product-market fit for the cost of a fancy coffee. You can always migrate to something more complex later. You can't get back the months spent configuring Kubernetes for an app with 50 users.

Try It Yourself

SendRec is open source. You can see exactly how we run everything.

The whole point of open source is that you don't have to take our word for any of this. Read the compose file, check the Dockerfiles, run it yourself.

$6/month. Real production. Real users. No excuses needed.

Top comments (0)