When I first discovered AWS serverless, it was the best thing since sliced bread. In fact, it was better than sliced bread. It was the future. So I quickly gathered all of my eggs and put them in the AWS basket.
The core principle of serverless is that you pay for what you use. You don’t pay a provisioned cost to host your code in the sky. You don’t pay for idle time. You pay for storage, compute, and data transfer. Throw in AWS Free Tier and you basically have free cloud access for all your side projects from now on.
But what about real projects? Production code. Something that drives business. What is the cost of that? Paying for what you use seems like a great idea until you have to figure out how much your application is going to cost to run over the next year, three years, and five years.
A serverless project is API Gateway, Lambda, DynamoDB, and S3, right? While this may seem true on the surface, there are actually a number of other services involved to piece together your app. CloudFront (content delivery), Route53 (DNS routing), and CloudWatch (logs, metrics, and alarms) are often forgotten components to a complete app.
But in addition to the forgotten services, you may or may not be aware of all the things you’ll be charged for when using these services. Lambda is not just a charge per invocation. You also have to pay for how much time your lambdas are running and how much memory they consume. For API Gateway, you pay per request but also for the amount of data transfer.
You can break costs down into two categories: compute and storage.
Data transfer. Nobody ever thinks about it, but they need to. Almost every AWS serverless service has a cost for data transfer. What does this mean for us?
First, make sure you’re architecting your solutions correctly. If you have an endpoint that retrieves a document out of S3 and feeds it through API Gateway, you are paying for data transfer out of S3 and out of API Gateway. A better solution would be to return a signed URL linking to the document, then have your client download the file. But that’s not what we’re here to talk about.
Knowing a rough estimate of how big your data is going to be is critical if you want to have a semi-accurate prediction on costs.
You need to get an idea of how many entities you have and how much data is included in those entities. Are you transferring the entire entity over the wire? Maybe just a subset? How many of each type of entity do you expect? Are you storing and retrieving big files out of S3?
Of course, you also need to consider how much of the data you’re storing. If you store 1 million entities a month, each with a size of 50 KB, that means you will be storing 50 GB monthly. If you store that data indefinitely, your storage costs will add up quickly.
You may not know this, but AWS services cost different amounts based on the region they operate out of. For example, 1 million lambda requests cost $0.20 when in US East (N. Virginia). But if you were to deploy over in Asia Pacific (Hong Kong), those same million requests would cost $0.28. If you’re building an application in the GovCloud, you get another hike on prices across the board.
If you’re deploying an application that needs to transfer data between regions, you’re going to have to pay for data transfer for that too.
Luckily, if you’re staying within the same region, a majority of the services don’t have data transfer costs between each other (meaning no costs to send data between Lambda and DynamoDB).
Here is a cost breakdown of some common services if you’re running out of US East (N. Virginia):
You might have some, all, or more of the services listed in the table above. Just pick and choose the services you use and start building up your model.
I’d argue this is the most important thing to consider. We all know that usage patterns are not evenly distributed across an application. Some things are one-time operations, like a user signup. Other things happen exponentially more often than others every day.
Let’s take an example application to illustrate our point. Yelp is a website that allows users to create an account, view ratings of places, and add ratings of their own. If we break down the cost of each of those major business processes, it might look something like this:
Create an account
Based on these numbers, you can get an idea of how much your app will cost to run if you estimate 1,000 new users a month, 2 million rating views, and 150,000 new ratings.
It’s all about knowing your business processes and how much you expect them to be used.
If you instead had just aggregated up that you have 10 lambdas, three endpoints, and some S3 storage, your estimations would suffer.
AWS doesn’t make it super easy to forecast your serverless apps. One way to get a decent estimate is to just run a load test on it. Better yet, estimate everything with the formulas from above, then run a load test to gauge accuracy.
Make adjustments where necessary in your math and hone in on your projections. Remember, projections shouldn’t be considered the truth. Your application is billed based on usage. It’s impossible to get that exactly right.
There are a couple of different ways you could load test your serverless application. You could use a third-party company like Artillery to do the load testing or you could use an AWS solution. Either way, this is going to be one of your most telling sources of how much your application will cost.
The obvious drawback to load testing is that you have to pay every time you do it, but we’re talking serverless here. It’s pennies on the dollar compared to traditional solutions.
Forecasting in a serverless world takes a little more effort than it has in the past. Cost models are predictable, but it all comes down to the business processes of your application.
The better you can estimate how many people will be using your application and which business flows are going to be used more than others, the more accurate your forecasts will be.
Good luck with your serverless journey. Enjoy the world of agility, mobility, and cost-effectiveness!