A good problem to have
Getting an app to the point where it simply works is an achievement. The product is mature, customers rely on it, and most weeks nothing dramatic happens. You’ve earned that.
Then you look at the hosting invoice. It grew while you were growing, which made sense at the time. Bigger servers to get through a busy season. A second database “just in case”. A service someone set up for a project that ended. Storage that only ever goes up. Nobody went back to check, because there was always something more urgent.
For a stable app, the bill often runs well ahead of what the work actually needs. Bringing it down is one of the most direct ways to improve the margin of a business that’s already working.
Where the money usually goes
The same handful of things turn up again and again:
- Oversized servers. Machines sized for a peak that happened once, or for a launch two years ago, now running mostly idle.
- An oversized database. Often the largest line on the bill. Sometimes it really needs that size. Often a few slow queries and missing indexes are the reason it looked like it did, and fixing those lets it shrink.
- Storage that never moves. Years of uploads, logs and backups on the most expensive storage class, when most of it is rarely read and could sit somewhere far cheaper.
- Forgotten services. Test environments, old load balancers, unused IP addresses, snapshots, and third-party add-ons still billing every month.
- Bandwidth. Files served straight from the app or storage when a CDN would deliver them faster and for less.
- Background job waste. Jobs that run every minute when hourly would do, jobs that retry forever, and worker machines kept running all night for work that takes ten minutes.
How I work
The rule is simple: measure first, change carefully, and prove the result.
- Read the bill properly. Break it down by service and resource, and tie each line to what it actually does for the app.
- Measure real usage. CPU, memory, database load, storage access patterns and traffic over a meaningful period, including your busiest days.
- Rank the opportunities by savings and risk. Low-risk, high-savings items go first. Anything that could affect customers gets a test plan and a way back.
- Make changes one at a time, watching the numbers after each, so if something misbehaves it’s obvious what caused it.
- Write down every saving, with the before and after cost and the date, so you can see it in the next invoices.
What I won’t do
Saving money by making the app fragile is a bad trade, so some things are off the table unless you decide otherwise with the full picture:
- No cutting backups or monitoring to trim a line on the invoice.
- No moving to a cheaper provider just to say the bill went down, if the move itself carries real risk.
- No changes during your busiest periods.
- No savings that depend on someone remembering to do something by hand every month.
Where the experience comes from
For seven years I was a senior engineer on a multi-tenant B2B SaaS product that grew from about four million to thirteen million dollars in annual revenue. I ran its production Postgres database, around a terabyte, and cut its AWS bill by six figures a year, mostly through the kinds of changes listed above: right-sizing, query fixes that let the database shrink, and moving rarely used files to cheaper storage. I’ve written about some of that work, including storage tiering for very large media libraries, on the site under Writing.
Documentation, so the savings last
Costs creep back when nobody remembers why things were set the way they were. When I finish, you have a plain-language overview of what runs where and what it costs, a savings ledger with before-and-after numbers, decision notes on each change and what to watch for, runbooks for scaling back up if traffic grows, and instructions for AI assistants so anyone changing your infrastructure with an AI tool knows the reasoning. You own all of it, along with the accounts, the code and the configuration. Any future developer or freelancer can pick it up.
Take a business like this one
The business in this section is a composite of the kind of company I talk to, not a named client. The numbers are the shape of the problem, not a case study.
Picture a company selling online training courses to clinics, with a web app built six years ago and a steady base of subscribers. New features are rare now. The two developers who built the bulk of it have moved on, and a part-time freelancer handles maintenance. The cloud bill has roughly doubled over three years while the customer count has stayed level.
What I’d do for a business shaped like this:
- Break down the bill. In a case like this, the database, video storage and a set of always-on servers usually account for most of it.
- Fix the queries behind the database’s high load, then shrink the database to match, with a tested way back.
- Move old course videos and uploads to a cheaper storage class, and serve videos through a CDN instead of straight from storage.
- Remove the leftovers: an old staging environment, unattached disks, years of snapshots nobody needs.
- Right-size the app servers using the measured traffic, and scale workers to zero overnight.
- Hand over the ledger and the notes so the freelancer can keep it lean and knows how to scale back up for a big enrolment period.
The owners keep focusing on courses and clinics, and the margin improves without anyone noticing a difference in the product.
What it costs
It starts with a fixed-price cost assessment: I read your bill and your usage and give you a written, ranked list of savings with the risk of each. The implementation is scoped and quoted from that list, and you choose which items to go ahead with. No percentage-of-savings arrangements and no lock-in.
What I need from you
Read access to your cloud or hosting accounts and billing, access to the code and monitoring, and a sense of your business calendar: your busy periods, planned launches and anything coming up that might need more capacity.
