Migrating to Hetzner 02/10/2025 We saved 76% on our cloud bills while tripling our capacity by migrating to Hetzner from AWS and DigitalOcean.
Background
All the software we build at DigitalSociety runs in the cloud. Prior to the migration we ran workloads on two platforms:
We use AWS for some of our core hosting needs (DNS via Route53 and sending emails via SES). We also chose AWS to host tap, our first SaaS product, using a variety of AWS services (ECS for container orchestration, RDS for relational databases, ALB for ingress, and a long tail of peripheral services, as is the AWS way). We chose AWS for familiarity since we have worked with it for nearly 15 years. We also prize their reliability, particularly when it comes to API stability. We automate as much of our infrastructure management as possible, and don't want to spend time chasing API breaking changes.
We used DigitalOcean Kubernetes to host several lightweight services, such as epcdata.scot, and monitoring services (Umami for web analytics, OpenObserve for telemetry, and Uptime Kuma for availability monitoring). We chose DigitalOcean for its relatively simple and cost-effective managed Kubernetes offering, where you pay for the cluster's resources (nodes, block storage, load balancers) but the controlplane is free. We chose Kubernetes for familiarity since we have worked with it for nearly 10 years. Although it requires a lot of boilerplate configuration, once it has been set up Kubernetes enables a frictionless developer experience for deploying applications quickly.
Why two cloud providers? Initially we used only DigitalOcean, but a data intensive SaaS like tap needs a lot of cloud resources and AWS have a generous $1,000 credit package for self-funded startups. Building tap with AWS credits let us experiment with our infrastructure needs without worrying about the cost.
Credits don't last forever
In the spirit of minimising our operational costs we opted to use AWS' serverless container runtime, Fargate. This lets us pay per-second for the CPU and memory used by our application. Fargate's monthly pricing scales down fairly well, with a minimal workload (0.25 CPU, 0.5 GiB RAM) costing around $10/month.
However, tap is a data-intensive SaaS that needs to be able to execute complex queries over gigabytes of data in seconds. Even though we use the blazingly fast Rust programming language and modern, efficient data technologies like Apache Arrow and DataFusion, we have found the minimum resource requirements for good performance to be around 2x CPUs and 4 GiB RAM – ideally even more to get a good experience for demanding queries.
How much does a 2x CPU, 4 GiB RAM container cost on AWS Fargate? Just over $70/month. We run two worker instances, which need these higher resources, along with smaller web instances and all the other infrastructure needed to host an application on AWS (load balancer, relational DB, NAT gateway, ...). All together, our total costs for two environments of tap grew to $449.50/month.
... continue reading