Series: How I Used Claude Code to Slash My Cloud Bill by 63%

The Moment I Noticed

I’ve been running everything in DigitalOcean since I decided to ditch my home equipment years ago. The appeal was “set it and forget it” – no hardware failures at 2 AM, no power outages taking down my sites, no maintaining physical boxes. And for years, it worked. My bill hovered around $125/month and I didn’t think twice about it.

Then March 2026 happened. My bill hit $198.28.

That’s when I opened up Claude Code and said something like “hey, can you figure out what I’ve got deployed in DigitalOcean and see if there’s a way to cut costs?” What happened next was a two-day infrastructure overhaul that I never expected.

The Audit: What Am I Actually Paying For?

Claude Code has access to my terminal, which means it has access to doctl – DigitalOcean’s CLI. I watched it systematically inventory everything in my account.

The Invoice Breakdown

The first thing Claude did was pull my invoice CSV:

doctl invoice csv preview /tmp/do_invoice_preview.csv

Here’s what was eating my money:

Line Item Monthly Cost
K8s Nodes (3x s-2vcpu-8gb-160gb-intel) $134.91
Container Registry (Professional tier) $20.00
Load Balancer $12.00
App Platform (reverse proxy) $10.00
Block Storage (51 GiB across 10 PVCs) $5.00
PA Sales Tax (6%) $10.92
Uptime checks, logging $0.00
Total ~$193

The K8s nodes were the big one – $135/month just for compute. And the killer detail? I had resized from 4GB to 8GB nodes on March 6th, which is why the bill jumped from ~$125 to ~$198. My previous months were all around $125.

The Archaeological Dig

Claude pulled the full invoice history going back to January 2017:

doctl invoice list

Ninety-eight invoices. I’ve been paying DigitalOcean for over 8 years. A quick mental calculation: roughly $12,000+ total over the lifetime of this account. That hit different.

What’s Actually Running?

Next, Claude enumerated every running workload in my Kubernetes cluster:

kubectl get pods --all-namespaces

Here’s what we found:

Namespace What’s Running Why?
default nginx (x2), reverse-proxy (x3), ubuntu utility pod Static site serving + reverse proxy
motivational-scheduler postgres, redis-master, redis-replica Database infra for an app
n8n n8n workflow automation My automation brain
rss-apps searxng, slack-channel-summary Search engine + RSS tools
wingmate postgres PVC only New app, just started
my-fleet Nothing. Zero pods. FleetDM – decommissioned

That last one. my-fleet. No running pods. But when Claude checked the persistent volume claims:

kubectl get pvc -n my-fleet
NAME                                         CAPACITY
data-fleet-mysql-0                           8Gi
redis-data-fleet-redis-replicas-0            8Gi
redis-data-fleet-redis-replicas-1            8Gi
redis-data-fleet-redis-replicas-2            8Gi

32 GiB of block storage sitting there doing absolutely nothing. Four persistent volume claims for a MySQL database and three Redis replicas that hadn’t had a pod attached in months. I had decommissioned FleetDM but never cleaned up the storage. That’s $3.20/month going straight to the trash.

The Kill

kubectl delete pvc --all -n my-fleet
persistentvolumeclaim "data-fleet-mysql-0" deleted
persistentvolumeclaim "redis-data-fleet-redis-replicas-0" deleted
persistentvolumeclaim "redis-data-fleet-redis-replicas-1" deleted
persistentvolumeclaim "redis-data-fleet-redis-replicas-2" deleted
kubectl delete namespace my-fleet
namespace "my-fleet" deleted

Gone. $3.20/month reclaimed instantly.

The Architecture That Got Us Here

To understand why the bill was what it was, you need to understand the architecture. Years ago, I built what I’d call a “highly sophisticated platform” for hosting my websites. At the time, I was running dynamic sites (WordPress, custom apps) that needed real compute. The architecture looked like this:

Internet
  → Cloudflare (DNS proxy)
    → DigitalOcean App Platform (reverse proxy container)
      → DO Load Balancer ($12/mo)
        → K8s Reverse Proxy StatefulSet (3 nginx replicas)
          → K8s Nginx StatefulSet (2 replicas + git-sync sidecars)
            → Static HTML files from git repo

Five hops to serve a static HTML page. Each layer made sense when it was added. The App Platform handled SSL termination. The load balancer distributed traffic to K8s. The reverse proxy routed domains to backends. The nginx pods served the actual content, pulling it from GitHub via git-sync containers.

But then I migrated all my websites to Hugo – a static site generator. The sites became just HTML, CSS, and JavaScript. No server-side rendering. No databases. No dynamic content. And yet they were still running through this entire pipeline.

The Epiphany

Here’s what I was actually running through all that infrastructure:

  • 8 static websites (Hugo-generated HTML)
  • 1 workflow automation tool (n8n)
  • 1 search engine (searxng)
  • 1 Slack summarizer
  • Postgres + Redis for the above

The static websites – which made up the vast majority of traffic – didn’t need Kubernetes at all. They didn’t need a load balancer. They didn’t need a reverse proxy. They needed… a CDN. Which is exactly what services like Cloudflare Pages provide. For free.

The Plan

Claude and I mapped out a multi-phase approach:

Phase 1: Move static sites to Cloudflare Pages – Eliminate the nginx StatefulSet, potentially the load balancer and App Platform.

Phase 2: Replace the App Platform with Cloudflare Tunnel – n8n doesn’t need to go through a $10/month App Platform and $12/month Load Balancer.

Phase 3: Downsize everything – With most workloads removed from K8s, the 8GB nodes were massive overkill.

Quick wins along the way:

  • Delete orphaned PVCs (done)
  • Downgrade the $20/month Container Registry
  • Evaluate if 8GB nodes were even necessary

What’s Coming Next

In Part 2, I’ll walk through the actual migration of 7 static websites from the K8s pipeline to Cloudflare Pages. It involved building a new GitHub Actions CI/CD pipeline, debugging Hugo’s habit of eating HTML comments, fixing a change detection bug that stumped us for a build cycle, and writing a Cloudflare Pages Worker to handle a domain redirect. All done conversationally with Claude Code in the terminal.

The punchline? By the time we were done with everything in this series, the bill went from $198/month to $74/month. That’s $1,488/year back in my pocket.


This entire series documents real infrastructure changes made in real-time with Claude Code (Anthropic’s CLI tool for Claude). Every command shown was actually executed, every error was actually encountered, and every fix was figured out in conversation. No staging environment, no dry runs – just Claude Code and I yolo’ing our way through production infrastructure.