In a time when hyperscaler marketing has successfully convinced everyone that auto-scaling microservices with Kubernetes are the bare minimum to run a three-user todo app while spending five-figure amounts monthly, it has never been easier to build affordable infrastructure.
Current state of the industry
I have been observing a growing obsession with complexity in the industry over the past ten years, which has led many developers to believe that the only way to build an application is at Netflix-level scale, abandoning all the principles of software engineering we developed over the past thirty years, starting with the most important one: it always depends on the use case.
Unless there is a good reason to do so, you probably do not need microservices that run on Kubernetes with high availability—especially when you are just starting out. Although building a monolithic application is considered a war crime nowadays, it is still a valid option to start with. Good software is all about understanding the domain and using the right tools for the right job. Both are non-trivial processes that evolve over time. Mastering them is a skill that you need to unlock yourself by going through and growing with it, not by being told. Every decision you make that you do not fully understand adds to the complexity on every aspect of your application. Keeping things as simple as possible for as long as possible is always a good way to go.
What we do
We are a small manufacturing company with fewer than 20 employees that has existed for almost 17 years now, serving a slowly growing customer base of 1,000+ small and medium businesses in the region of Central Europe. Operating hours are 8am to 5pm, from Monday to Friday, and the same applies to our customers. We are proud of building products with only the essential features that actually matter. By avoiding unnecessary complexity and trendy add-ons like AI, we can offer durable and affordable solutions to our customers that are plain simple to use and maintain—and that shall also apply to our software.
Over the next few years, I will focus on shaping our company’s digital infrastructure. With operating hours from 8am to 5pm within a single timezone and expected low traffic during the day, we can afford to run our software with a pretty simple server setup. High availability is not a must, and being offline for a few hours a day is not a big deal.
As our budget is pretty tight, pricing has to be as low and as predictable as possible to get the job done. Our internal goal is to stay below €150 per month for our entire infrastructure as long as possible.
What we need to host
For now, we need three things:
Website
Our current website was built with WordPress around 15 years ago, covering some content sites, form pages, blog posts, a list of available products, and a login area for customers. The customer area has some basic features around so-called projects that enable customers to manage and exchange project-related items like documents (inquiries, invoices) and some specific project-related forms. It also lets customers download product-related documents like product specifications, technical diagrams, and more, including personalized pricing.
The good news is that they failed to add more features to the site in the recent past, which makes it more manageable to maintain or even rebuild.
The bad news is that it’s a complete mess. It was built about 15 years ago by a hobbyist programmer with little to no knowledge of PHP and CSS. Over the last 10 years, it has only been maintained and further developed on the side for 3–6 hours a week, which is why many bugs have not been solved and features have not been polished. After working my way through the code and the database, it would take me more time and a lot of painkillers to continue maintaining the current site, especially when it comes to adding new features or integrating our new backend. Every piece of code and every database table there has to be touched and rebuilt anyway to be able to work with it and add new features later on.
Backend
In order to feed data into the website (and later the CRM and possibly other systems) that would be needed later, and to ensure centralized data management, we are also in need of a proper backend. Separate from the website and separate from PHP and WordPress. So here we have to develop the standard features like a REST API with functionality such as registration, login, database access, email dispatch, file handling, and much more.
Custom CRM/PIM System
Last but not least, we then need an internal company system where only employees can log in and where everything comes together. From this system, all things that concern the company should be controllable. This includes all data related to customers, like quotation preparation, invoicing, shipping, and handling complaints. As well as everything related to the manufacturing of our products, including settings for various product sheets and diagrams and the ability to maintain prices for products and individual industries.
What infrastructure we will start with
For operating the described software, we have decided to go with the simplest setup possible, namely running it all together on a single server. This reduces both the maintenance effort and the deployment complexity and simplifies and speeds up communication between the services. With proper backups and continuous archiving techniques for things like databases, we can easily recover from any kind of failure within 30 minutes or less.
Compute - Server(s)
I have been hosting my own servers for over 10 years now, and the provider that I have stuck with for the last 5 years is Hetzner. Some other affordable and trustworthy providers like Netcup, Scaleway, and OVHCloud exist, but Hetzner is still my go-to provider when it comes to affordable and reliable servers that are easy to manage with a ton of features, which is especially true for their virtual cloud servers.
Hetzner operates across various locations in Germany (2), Finland (1), Singapore (1), and the US (3), although not all locations are available for all services.
I have put together a complete list of all available cloud servers (virtualized) including some specs, highlighting the ones that I have chosen for our infrastructure. For everything non-production related or services with very low and infrequent traffic, I have chosen the shared servers CX22 (2 vCPU / 4GB RAM) and CX32 (4 vCPU / 8GB RAM), both running on x86 type CPUs, ensuring maximum compatibility with all kinds of tasks and stacks.
For everything else, dedicated CPU core configurations like CCX23 (4 vCPU / 16GB RAM) or CCX33 (8 vCPU / 32GB RAM) are a must.
Server | CPU-Type | architecture | vCPU | RAM | NVMe SSD | Traffic included | Price per month | price per hour |
---|---|---|---|---|---|---|---|---|
CX22 | Shared | x86 (Intel® Xeon® Gold) | 2 | 4 GB | 40 GB | 20 TB | €4.51 | €0.007 |
CX32 | Shared | x86 (Intel® Xeon® Gold) | 4 | 8 GB | 80 GB | 20 TB | €8.09 | €0.0134 |
CX42 | Shared | x86 (Intel® Xeon® Gold) | 8 | 16 GB | 160 GB | 20 TB | €19.52 | €0.0325 |
CX52 | Shared | x86 (Intel® Xeon® Gold) | 16 | 32 GB | 320 GB | 20 TB | €38.56 | €0.064 |
CPX11 | Shared | x86 (AMD EPYC™ 7002) | 2 | 2 GB | 40 GB | 20 TB | €5.18 | €0.0084 |
CPX21 | Shared | x86 (AMD EPYC™ 7002) | 3 | 4 GB | 80 GB | 20 TB | €8.98 | €0.014 |
CPX31 | Shared | x86 (AMD EPYC™ 7002) | 4 | 8 GB | 160 GB | 20 TB | €16.18 | €0.0261 |
CPX41 | Shared | x86 (AMD EPYC™ 7002) | 8 | 16 GB | 240 GB | 20 TB | €29.99 | €0.0496 |
CPX51 | Shared | x86 (AMD EPYC™ 7002) | 16 | 32 GB | 360 GB | 20 TB | €65.33 | €0.105 |
CAX11 | Shared | ARM64 (Ampere® Altra®) | 2 | 4 GB | 40 GB | 20 TB | €4.51 | €0.0073 |
CAX21 | Shared | ARM64 (Ampere® Altra®) | 4 | 8 GB | 80 GB | 20 TB | €7.72 | €0.0124 |
CAX31 | Shared | ARM64 (Ampere® Altra®) | 8 | 16 GB | 160 GB | 20 TB | €14.86 | €0.020 |
CAX41 | Shared | ARM64 (Ampere® Altra®) | 16 | 32 GB | 320 GB | 20 TB | €29.14 | €0.0466 |
CCX13 | Dedicated | x86 (AMD EPYC™ 7003/9654) | 2 | 8 GB | 80 GB | 20 TB | €14.86 | €0.020 |
CCX23 | Dedicated | x86 (AMD EPYC™ 7003/9654) | 4 | 16 GB | 160 GB | 20 TB | €29.14 | €0.0466 |
CCX33 | Dedicated | x86 (AMD EPYC™ 7003/9654) | 8 | 32 GB | 240 GB | 30 TB | €57.70 | €0.0925 |
CCX43 | Dedicated | x86 (AMD EPYC™ 7003/9654) | 16 | 64 GB | 360 GB | 40 TB | €114.82 | €0.184 |
CCX53 | Dedicated | x86 (AMD EPYC™ 7003/9654) | 32 | 128 GB | 600 GB | 50 TB | €229.06 | €0.3671 |
CCX63 | Dedicated | x86 (AMD EPYC™ 7003/9654) | 48 | 192 GB | 960 GB | 60 TB | €343.30 | €0.5501 |
Should these server configurations not be sufficient for our needs later on, we still have the option to scale vertically with very low cost, switching to non-virtualized dedicated servers like the EX44 (14 Cores / 64GB RAM) or anything else above. Although we will lose the convenience of Hetzner’s cloud console to manage everything around cloud servers, this is a very good option for us.
Server | CPU | CPU cores | RAM | NVMe SSD | Uplink | Price per month | setup fee |
---|---|---|---|---|---|---|---|
EX44 | Intel® Core™ i5-13500 | 6+8 HT | 64 GB DDR4 | 2× 512 GB (Gen 4) | 1 Gbit/s Port | €46.41 | €46.41 |
EX101 | Intel® Core™ i9-13900 | 8+16 HT | 64 GB DDR5 ECC | 2× 1.92 TB (Gen 4) | 1 Gbit/s Port | €99.96 | €46.41 |
AX42 | AMD Ryzen™ 7 PRO 8700GE | 8 SMT | 64 GB DDR5 ECC | 2× 512 GB (Gen 4) | 1 Gbit/s Port | €54.74 | €46.41 |
AX52 | AMD Ryzen™ 7 7700 | 8 SMT | 64 GB DDR5 ECC | 2× 1 TB (Gen 4) | 1 Gbit/s Port | €70.21 | €46.41 |
AX102 | AMD Ryzen™ 9 7950X3D | 16 SMT | 128 GB DDR5 ECC | 2× 1.92 TB (Gen 4) | 1 Gbit/s Port | €123.76 | €46.41 |
EX130-R | Intel® Xeon® Gold 5412U | 24 HT | 256 GB DDR5 ECC reg. | 2× 1.92 TB (Gen 4) | 1 Gbit/s Port | €159.46 | €94.01 |
EX130-S | Intel® Xeon® Gold 5412U | 24 HT | 128 GB DDR5 ECC reg. | 2× 3.84 TB (Gen 4) | 1 Gbit/s Port | €159.46 | €94.01 |
AX162-R | AMD EPYC™ 9454P | 48 SMT | 256 GB DDR5 ECC reg. | 2× 1.92 TB (Gen 4) | 1 Gbit/s Port | €236.81 | €94.01 |
AX162-S | AMD EPYC™ 9454P | 48 SMT | 128 GB DDR5 ECC reg. | 2× 3.84 TB (Gen 4) | 1 Gbit/s Port | €236.81 | €94.01 |
:::: Storage (S3)
Although storage is already assigned to every kind of server, either cloud or dedicated ones, we will need additional storage that is detached from the server infrastructure. This storage will be used for backups, continuous archiving, and for every other document the application needs to manage.
When we talk about storage, Amazon S3 (Simple Storage Service) is usually the first name that comes up—and for good reason. Whether you’re saving images for a website, backups for an app, or big data for analytics, S3 offers a scalable, durable, and highly available solution with a ton of features like replication, versioning, object locks, object meta information, and many more. Almost two decades later, S3 has evolved to become the de facto standard, which has forced many providers to build and offer S3-compatible solutions themselves to be able to compete.
S3-compatible storage is usually billed based on storage used, data transfer, and requests for retrieving, updating, and writing objects or related data. Depending on the provider, pricing complexity ranges from easy to PhD level, which is why I will work here with a greatly simplified pricing matrix.
Provider | Type | GET | PUT | DELETE | LIST | Retrieval | Data Transfer | Always Free | Storage |
---|---|---|---|---|---|---|---|---|---|
AWS | S3 Standard | €0,0004/1000 | €0,005/1000 | free | €0,005/1000 | free | free (internal), 100 GB/month free; €0,09/GB for next 10 TB (external) | 5 GB, 20.000 GET, 2.000 PUT/LIST, 100 GB DTO | €0,0245/GB (first 50 TB) |
AWS | S3 Glacier Flexible Retrieval | €0,0004/1000 | €0,05/1000 | free | €0,05/1000 | Restore after 12 hours free | free (internal), 100 GB/month free; €0,09/GB for next 10 TB (external) | 5 GB, 20.000 GET, 2.000 PUT/LIST, 100 GB DTO | €0,0036/GB |
Cloudflare | R2 Standard | €0,00036/1000 €0,36/1.000.000 | €0,0045/1000 €4,5/1.000.000 | free | €0,0045/1000 €4.5/1.000.000 | free | free (both) | 10GB, 10.000.000 GET, 1.000.000 PUT/LIST, free DTO | €0,015/GB |
Hetzner | Object Storage | free | free | free | free | free | free (internal), €1/TB (external) | - | €4.99/TB |
Hetzner offers the most affordable but also the most immature and unreliable storage solution of the listed ones. Nonetheless, we will start using Hetzner S3 as our main storage and sync the data to AWS S3 as a backup, as both also have versioning and replication features, hoping they will catch up in the next 12 months. Cloudflare R2, on the other hand, does not offer versioning but comes in handy when publishing assets or images to the web for our website. As we also plan to use the Cloudflare Network to publish and protect our website and all other services, this would be a perfect fit.
:::: Serverless
Since we decided to exchange complexity for downtime, we will need to find some alternatives that increase the overall uptime in some areas, especially when an immediate response may not be needed. I am thinking of the following use cases:
- Any public webpage that can be generated beforehand
- Any kind of tracking or analytics, like emails, page views, or marketing campaigns
- Any kind of user actions that originate from an email, like double opt-in confirmations/cancellations, participating in surveys, or other similar things
For these use cases, everything that is managed/serverless will be a great improvement in general uptime and responsiveness for our users. The most promising candidates for these use cases are the following (again, with a greatly simplified pricing matrix):
Service | Providers | Pricing | Always Free | Description |
---|---|---|---|---|
Cloudflare Free Plan | Cloudflare | free | - | Application Service with basic CDN, SSL/TLS, DDoS protection, global content delivery and many more |
Cloudflare Zero Trust | Cloudflare | free up to 50 users | - | Security Service to protect all your network resources with Cloudflare, like Servers, SSH access and more |
Cloudflare Pages | Cloudflare | free | - | Serverless hosting of static websites in Cloudflare’s network |
API Gateway (REST API) | AWS | €0,0035/1000 Req after free tier | 1.000.000 REST API calls / month | Serverless HTTP API service (like REST) to connect other AWS services |
Lambda | AWS | €0,00020 / 1000 Req €0,0000166667 / GB-second after free tier | 1.000.000 Req + 400.000 GB-seconds / month | Serverless compute service to run your code in a pay-as-you-go manner |
DynamoDB | AWS | €0,0007625 / 1000 Writes €0,0001525 / 1000 Reads €0,25/GB after free tier | 25GB storage + 25 RCU + 25 WCU / month | Serverless NoSQL database |
SQS (Standard) | AWS | €0,00040 / 1000 Req | 1.000.000 Req / month | Serverless message queues |
SES | AWS | €0,10 / 1000 emails €0,12 / GB of attachments | – | Serverless email service to send and retrieve emails |
EventBridge | AWS | free within same account/service or €0.001 / 1000 for other events | - | Serverless scheduling service to trigger other AWS services on a schedule |
These tools are built for scale but still come in handy for smaller businesses like ours, especially when dealing with low traffic.
:: Conclusion
So for the start of the project, it looks like we will need around €105 before tax to host our website and all other services, whereas serverless and S3 storage pricing will surely grow over time and usage:
Type | Specs | Price per month | purpose |
---|---|---|---|
Cloudflare Free Plan | CDN, SSL/TLS, DDoS Protection etc | €0,00 | Free Cloudflare account to manage our Domains, DNS and more |
Cloudflare Zero Trust | ZeroTrust services for servers and applications | €0,00 | Zero Trust addon to secure our servers and applications |
Hetzner S3 | - | €4,99 | Main storage for our documents and backups |
AWS S3 | - | €0,00 | Backup storage for our documents and backups |
Cloudflare R2 | - | €0,00 | Main storage for public assets and images that are need for our website |
Cloudflare Pages | - | €0,00 | Used to host the public, pregenerated pages of our website |
IdP Server | CX22 - 2vCPU / 4GB RAM / 40GB SSD (shared) | €4,51 | Used to host our public Identity-Provider (oauth2) application, needed for Cloudflare Zero Trust user management |
Test Server | CX32 - 4vCPU / 8GB RAM / 80GB SSD (shared) | €8,09 | Used to host all developed applications like our website, backend and crm for testing |
Tooling Server | CCX23 - 4vCPU / 16GB RAM / 160GB SSD (dedicated) | €29,14 | Used to host all developer related stuff like a build server and server monitoring software |
Production Server | CCX33 - 8vCPU / 16GB RAM / 240GB SSD (dedicated) | €57,70 | Used to host all developed applications like our website, backend and crm for production |