Skip to Content
← All Work

Case study · Prepare.sh · 2025–2026

Moving core infrastructure across cloud boundaries

Migrating CDN, object storage, and databases from Azure toward Cloudflare R2, D1, and Workers, alongside multi-region bare-metal Kubernetes infrastructure on Hetzner.

At a glance

Monthly infrastructure cost, as reported by the company
~$7,900 → ~$330
CDN, object storage and databases
Azure → Cloudflare
Cloudflare services adopted
R2 · D1 · Workers

Role · Founding Engineer, Cloud & DevOps

What I did

  • Contributed to the migration of CDN, object storage and databases from Azure to Cloudflare R2, D1 and Workers.
  • Worked on the bare-metal Hetzner K3s infrastructure the services sit alongside.
  • Developed reusable Terraform modules and Helm deployments.

Team context

What the team did

  • The platform, its content and its application code were built by the wider team.
  • The company’s cost figures reflect the migration as a whole, not my individual work.
  • Later scaling of the platform was handled by others. I was not directly involved in it.

01

Context

Prepare.sh is a developer-education platform serving approximately 10,000 users. Its first infrastructure ran on Azure: AKS, Azure DevOps pipelines, Container Registry, Functions, Event Hub, Blob Storage and Azure CDN.

This case study covers the move of the platform’s shared services, CDN, object storage and databases, off Azure. The compute side of the move is covered in the developer-environments case study.

02

Problem

Core services ran on Azure while the team relied on hyperscaler cloud credits. The aim was to move off those credits onto a self-managed stack and significantly cut recurring infrastructure spend.

03

Constraints

  • The platform had approximately 10,000 users.
  • CDN, object storage and databases all needed a new home, not just compute.
  • A small engineering team.
  • The services had to work alongside a new multi-region bare-metal K3s cluster.

04

Architecture

Service migration mapAzure AKS and vCluster moved to K3s on Hetzner. Azure DevOps pipelines moved to GitHub Actions. Azure CDN, object storage and databases moved to Cloudflare CDN with Workers, R2 and D1.BEFORE · AZUREAFTER · SELF-MANAGED + CLOUDFLARECOMPUTEAzure AKS + vClusterCOMPUTEK3s on Hetzner bare metalCI/CDAzure DevOps YAML pipelinesCI/CDGitHub ActionsCDNAzure CDNCDNCloudflare CDN + WorkersOBJECT STORAGEAzure Blob StorageOBJECT STORAGECloudflare R2DATABASESAzure-hosted databasesDATABASESCloudflare D1
Fig. 01: Service migration map, Azure to Hetzner and Cloudflare

Target architecture after the migration.

  • CDN, object storage and databases moved to Cloudflare CDN with Workers, R2 and D1.
  • Compute runs on a bare-metal Hetzner K3s cluster.
  • GitHub Actions handles delivery to the cluster.
Developer environment architectureGitHub Actions deploys to a bare-metal Hetzner K3s cluster that runs isolated learner environments. Static assets, object storage and databases sit on Cloudflare R2, D1 and Workers. A dashed box shows the earlier Azure AKS and vCluster setup.AFTERGitHub ActionsCI/CDK3s · Hetzner bare metalself-managed clusterenvenvenvisolated · provision <1 minCloudflareR2object storageD1databasesWorkers+ CDNBEFOREAzure AKS · vClusterDocker-in-Docker limits · provisioning ~2–3 min · ACR, Functions, Event Hub, Blob, CDN
Fig. 02: Architecture

05

Alternatives

What happened

The starting point was the Azure stack, funded in part by hyperscaler cloud credits.

Retrospective analysis

Stay on Azure at full price
Simplest operationally, but keeps recurring spend tied to a hyperscaler once credits end.
Another hyperscaler
Changes the vendor, not the cost structure or the dependency.
Self-host everything
Maximum control, but also owning CDN, storage and database operations, which is a lot for a small team.

06

Decision

Move CDN, object storage and databases to Cloudflare R2, D1 and Workers, and run compute on self-managed bare-metal K3s. The documented drivers were moving off hyperscaler cloud credits and cutting recurring infrastructure spend.

07

Implementation

  1. 01

    CDN

    Moved content delivery from Azure CDN to Cloudflare.

  2. 02

    Object storage

    Moved object storage to Cloudflare R2.

  3. 03

    Databases

    Moved databases to Cloudflare D1.

  4. 04

    Edge logic

    Used Cloudflare Workers as part of the platform architecture.

  5. 05

    Repeatability

    Reusable Terraform modules and Helm deployments standardized provisioning and removed manual configuration steps.

08

Results

  • Company-reported: infrastructure cost fell from roughly $7,900 per month on Azure to roughly $330 per month after the migration. The figure comes from the company’s founder and reflects the migration as a whole, not my work alone.
  • The team moved off hyperscaler cloud credits.
  • CDN, object storage and databases now run on Cloudflare R2, D1 and Workers.

Measurable outcomes

~$7,900 → ~$330 / month
Reported infrastructure cost, before and after the migration
Company-reported
≈96% lower
Monthly cost reduction: ($7,900 − $330) ÷ $7,900
Calculated
~$90,800 / year
Annualized difference ($7,570 × 12), assuming the monthly figures hold
Calculated
CDN · storage · databases
Moved from Azure to Cloudflare CDN with Workers, R2 and D1
From my work
Off cloud credits
The team no longer depends on hyperscaler credits
Company-reported
Monthly infrastructure cost before and afterThe company reported infrastructure costs of about 7,900 dollars per month on Azure, and about 330 dollars per month after the migration, roughly 96 percent lower.$0$4,000$8,000Azurebefore~$7,900 / monthAfter migrationafter~$330 / month≈96% lower (calculated)
Fig. 03: Monthly infrastructure cost before and after the migration. Company-reported; reflects the migration as a whole.

09

Trade-offs & Failure Modes

From the project

  • A self-managed stack, with Cloudflare services in place of Azure ones, trades convenience for control over cost.

General analysis

Data migration
Moving databases and objects between providers needs verified copies, a cutover plan and a way back if something is wrong.
Capability differences
D1 is SQLite-based, so features and limits differ from a typical managed relational database.
Multi-provider operations
Spreading services across Cloudflare and Hetzner means more dashboards, credentials and failure domains to monitor.
Cost visibility
Savings need measuring against the old bill, including the time spent operating the new stack.

10

Lessons

  • Know which constraint is driving the move: here, cost and dependence on credits.
  • Migrate the parts that are cheapest to move first and keep a path back.
  • Separate the services you move from the services you operate, and be clear about which is which.

11

Questions People Ask

The follow-ups this work tends to raise, answered directly.

Why move off Azure?

The platform was running on hyperscaler cloud credits. Moving to a self-managed stack removed that dependency and significantly cut recurring infrastructure spend.

What moved to Cloudflare?

The CDN, object storage and databases, onto Cloudflare R2, D1 and Workers.

What runs on servers instead?

Compute runs on a multi-region bare-metal Hetzner K3s cluster.

How much did it save?

The company’s founder reported infrastructure costs of roughly $7,900 per month on Azure versus roughly $330 per month after the migration, about 96% lower. That is the company’s result for the migration as a whole, not mine alone.

How does D1 differ from a managed Azure database?

D1 is SQLite-based, so features and limits differ from a typical managed relational database, which is worth planning for in any migration.

General context