Database economics: an Amazon RDS reflection

Carlota Soto
7 min readMay 31, 2024

--

Everyone loves a graph that goes up right: new users, retention, revenue, costs… What — you don’t like to see your costs rising? 😉

Watching your database costs grow significantly as you scale is one of the unfortunate realities of building. But it’s common to see them growing much more than you expected. Why is that?

After working in database companies for years and talking to many companies startled by this, I’ve come to learn that the answer has three parts:

  1. As soon as you hit production, you’ll need more databases than you initially thought.
  2. You’ll pay for your non-prod databases 24x7 even if you don’t need them.
  3. You’ll be overprovisioning your production database significantly.

The costs of real production deployments

Let’s say you’re building and scaling a B2B SaaS. What will your deployment look like?

Of course, you have a production database. (Many teams have more than one, but let’s keep it simple). As your user base grows, so does the size of this database, both in storage and compute.

So far, so good — all of us get this part. But what it’s easier to miss when forecasting costs are all the non-prod databases you’ll team will need as you scale.

When your customer base grows, you might start running a staging database. Ideally, this database will replicate your production data, so you can catch potential issues before they reach your customers. This will be expensive.

You’ll also might need some sort of testing database. Your CI/CD pipelines will use this database to verify that new code changes don’t introduce bugs or regressions. This database won’t require as much storage or compute resources as your staging or prod databases, but it will still add to your costs.

Most importantly, you’ll surely need at least one development database - as your engineering team grows, you’ll need a few. Each developer on your team will need to work on new features, bug fixes, and improvements to your application. Dev databases can be small, but it’s very normal to have many — and the costs can really add up, as we’ll see in a minute.

So, let’s imagine your company is really scaling. Everything is going great, you’re onboarding more and more customers, your engineering team is growing. You might end up with a deployment that looks somewhat like this:

  • One primary database
  • One staging database
  • One test database
  • Ten development databases

We’re suddenly looking at 13 database instances that need to be spooled up.

By this stage, if you’re running in a managed platform like Amazon RDS (the most vanilla example we can think of), you’re gonna feel the pressure of reducing database costs as much as possible.

Let’s say your focus is specifically on reducing compute costs, something that seems a lower-hanging fruit than tackling your data. You may be starting to consider one of these two strategies to try to lower those costs down:

  1. One of your team members could be charged with monitoring your instance usage and try to optimize it, e.g. by pausing and restarting instances, looking for opportunities to migrate to smaller instances, handling resizes, and so on.
  2. You could also try to manage all of this by a series of IaC scripts that provision instances as needed. If you’re running on AWS, you’d need someone in your team who knows how to do DevOps with your infra.

There’s also a third scenario that I’ve actually seen a lot:

Everything Everywhere All at Once. You give up, spin these databases up, and leave them up for all eternity. It’s just too much work (annoying work) to optimize this usage, and you have more important things to spend your time on. A few extra dollars a month are not that much if compared to how much money your company is burning — it’s not a good use of your engineers time to babysit RDS costs. Right?

How much is this going to cost?

We all relate to the everything-everywhere approach; there’s good logic to it, and that’s why it’s more often than not what companies do. But how sustainable is it? And how much could we actually save if things were a little leaner in RDS billing?

Let’s do an exercise. First, let’s take a quick look at Vantage to see how much RDS instances cost on average.

The lowest we’ll be able to go is the db.t4g.micro. This instance offers two vCPUs, 1 GiB of memory, and up to 5 Gibps of bandwidth. The cost is $0.016 per hour. So here we’re doing:

  • $0.016 * 730 * 13 = $186.88 per month in compute costs

This is not a bad cost for your machines. If your company is paying for a team of 10 developers, it is literally lunch money.

But this is the rock-bottom option. You might be able to get away with a micro instance for a few developer databases when testing a small feature, but it’s unlikely for a full deployment, especially as you scale. Most definitely, you won’t be using this instance for your production database.

So, let’s go to the other end of the spectrum. A db.r6i.32xlarge will give you 128 vCPUs, 1024 GiB of memory, and 50 Gibps of bandwidth. This is 1000 times more expensive than the db.t4g.micro at $16/hour. If your entire deployment used this instance type, it would cost you 1000X more:

  • $16 * 730 * 16 = $186,880 per month in compute costs

Ok. Unless you get lunch from Atelier Crenn every day, this has probably gone beyond lunch money.

For most mid-size production teams, it’ll be somewhere in the middle. You’ll probably end up using something akin to a db.r6i.32xlarge for production and staging, but closer to db.t4g.micro for your development databases.

For example:

  • Production database: db.r6i.32xlarge = $16/hour
  • Staging database: db.r6i.16xlarge (half the size of production) = $8/hour
  • Test database: db.t3.medium = $0.0376/hour
  • Development databases (10 total): 10 db.t4g.micro = $0.016/hour each

This would cost approx.:

  • Production database: $16 * 730 = $11,680
  • Staging database: $8 * 730 = $5,840
  • Test database: $0.0376 * 730 = $27.448
  • Development databases: $0.016 * 730 * 10 = $116.80

The total monthly compute cost for this deployment would be $17,664.25. Somewhat of a fancy lunch, we could say.

The essential message of this reflection is this: when you’re forecasting costs in a vanilla managed database like RDS, consider that,

  • You will be provisioning your production database with a large instance to cover your peak load.
  • Your production database will be your most expensive instance, but you’ll need many more instances as you scale. Don’t forget to contemplate the entirety of your deployment.
  • Whatever you provision today, it’s the lowest you’ll pay. Databases don’t tend to need lower compute over time.
  • These costs will most likely be always on unless you commit to dedicating engineering resources to optimize this bill.

What if your non-prod databases could scale to zero?

Now, let’s imagine a hypothetical scenario where your non-production databases can scale to zero. This would help us understand the potential for optimization here — i.e. how much money are we paying to AWS for no reason at all.

Scaleto zero means that instead of running 24x7, these databases only run when they are actually used, and you only pay for true usage. How impactful this would be in terms of $$ saved?

Imagine the following usage patterns for your non-prod databases:

  • Staging database: Used for about 8 hours per day (240 hours/month)
  • Test database: Used during CI/CD runs for around 2 hours per day (60 hours/month)
  • Development databases: Active for about 4 hours per day on average (1200 hours/month for 10 of them)

If the instances of the following example could scale to zero, this non-prod deployment would now cost us:

  • Staging database: $8 * 240 = $1,920
  • Test database: $0.0376 * 60 = $2.256
  • Development databases (10 total): $0.016 * 1200 = $19.20

This would make a total of $1,941.456 per month in compute for non-prod databases, corresponding to a 23% reduction in your compute bill. Not bad.

What if compute in your production database could autoscale?

Now, let’s consider another hypothetical optimization: autoscaling your production database.

If your compute could autoscale, your production database could dynamically adjust its capacity based on actual usage. Instead of paying for max capacity 24x7, your database could scale down during periods of low demand, reducing your prod costs without having to manually do anything.

This is also a source where we’re paying AWS for no reason. Teams spend so much money just because of overprovisioning compute. But how much?

To put a $$ number to how impactful this feature could be in terms of costs, let’s imagine your production database usage follows this pattern:

  • 20% of the time, it runs at full capacity (100%).
  • 80% of the time, it runs at a much lower capacity (30%).

Using the db.r6i.32xlarge instance as an example, this is:

  • Full capacity (20% of the time): 20% * 730 hours = 146 hours
  • Lower capacity (30% of the time): 80% * 730 hours = 584 hours
  • Full capacity cost: $16 * 146 = $2,336
  • Lower capacity cost: $16 * 0.3 * 584 = $2,803.20

In this estimation, the monthly compute cost for the production database would lower down to:

  • $2,336 + $2,803.20 = $5,139.20 per month

If we combined this with the savings from letting the non-prod databases scale to zero, we would be looking at a 60% reduction of the monthly compute costs. All of this is without manual work or compromising performance in any way. These savings would come simply from no longer paying AWS for resources you don’t use.

Breaking the cycle

Database deployments often get more expensive than they should because 1) as you scale, you start needing many non-production databases that slowly bloat your bill; 2) you pay for 24/7 usage even if you’re only running non-prod databases for a few hours; 3) you’re paying for peak capacity in your production database 24/7.

That’s why serverless databases like Neon are becoming very popular — they can help you escape this. Scale to zero reduces the costs of non-prod databases, and autoscaling adjusts compute costs for your production database automatically.

Teams can stop worrying about manually trying to optimize resources for database instances and spend their attention somewhere else.

--

--

Carlota Soto

PMM Lead @ Neon. I write, cook, run, read, surf, and rewatch the same movies over and over again. Made in 🇪🇸, based in 🇺🇸.