I believe the study of the cost is no longer restricted to procurement. It is an integral part of the software architecture activity. It is important for the solution architect to understand the cost (visible and hidden) implications of choosing a particular technology.
Software architectures designed on abstractions like containers, orchestration and more recently serverless (FaaS) increases the development velocity and reduces complexity and cost. But the cost of running an application depends on many factors such as the choice of database, application adoption, hosting etc.
Thus the complexity about the cost of an application implies that the organization can’t rely on their development teams to make that decision and needs a hands-on decision maker. Even though AWS Lambda Pricing is pretty straightforward but the cost of running a serverless application is complex and involves many challenges.
AWS Lambda Pricing: An Overview
AWS Lambda is a classic example of the series of cloud technology products popularly known as serverless or function-as-a-service or FaaS.
AWS Lambda is basically a piece of code that runs in an ephemeral container which terminates after serving its purpose i.e. single invocation tasks. Based upon these invocations, you pay only for what you use. Each of the Lambda function is configured based on the memory size (GB) and execution time measured in milliseconds.
Let’s elaborate on the general pricing model:
#1. Memory Size (GB): This is the maximum memory size configuration that you allocate to your function from the AWS console. This isn’t the actual memory which is used by the function. This suggests that even if you reduce your function’s memory usage but do not tweak this configuration, you won’t be able to observe any reduction in the cost.
#2. Execution time (ms): This is the actual time that a function takes to execute its code logic. Additionally, for example, if your function is making an outgoing call and is waiting till the response comes, the time spent idle will be also counted in the function’s execution time.
The overall duration of the executing functions is calculated from the time your code begins executing until it returns or terminated, rounded up to the nearest 100ms.
To calculate the cost of each function, both these values are multiplied together to produce a unit GB-sec. Since GB-sec depends on many factors, it is not predictable.
Here’s a chart which demonstrates the cost of executing 100,000 invocations of a Lambda function over the varying time. One must note that the execution time of the Lambda function also depends on the language runtime and 3rd-party dependencies. Image source here.
Note: GB-sec is just a composite unit used to measure AWS Lambda offering. Nor does it showcase gigabyte nor a second. The current price of AWS Lambda is
- Compute charges: $0.00001667/invocation
- Request charges: $0.2/M requests
AWS Lambda Pricing vs EC2
Let’s compare the charges between AWS Lambda & EC2 for two different use cases:
#1. Low Compute Use Case
For low compute use cases (such as scheduled CRON jobs, transform on upload, read/write to DynamoDB, serverless authentication) consider the following scenario for our application:
- Allocated memory 512 MB
- No. of invocations: 20,000 times/month
- Execution duration: 1 sec
AWS Lambda Pricing Calculation
GB-sec = 20,000 * 512/1024 = 10,000 GB-sec
Compute charges = 10,000 * $0.00001667 = $0.1667
Request charges = (20,000/1,000,000) * $0.2/Million = $0.004
Total charges = $0.1667 + $0.004 = $0.1707
EC2 Pricing Calculation
Even if we consider the smallest available on-demand instance t2.nano, the monthly cost would be $5.832
#2. High Compute Use Case
For high compute use cases (such as ETL jobs, real-time data processing & video processing) consider the following scenario for our application:
- Allocated memory 2496 MB
- No. of invocations: 30,000,000 times/month
- Execution duration: 500 sec
AWS Lambda Pricing Calculation
GB-sec = 30,000,000 * 0.5s * 2496/1024 = 36,562,500 GB-sec
Compute charges = 36,562,500 * $0.00001667 = $609.5
Request charges = (30,000,000/1,000,000) * $0.2/Million = $6
Total charges = $609.5 + $6 = $615.5
EC2 Pricing Calculation
Considering this as a high-end compute work, even if we consider m4.large with 8GB memory, the monthly cost would be $138.2424
#1. On demand instances aren’t a suitable option. Lambda is designed for functions that are to be executed rapidly after being triggered by the events. To get the benefit of the on-demand EC2 instances, you will have to spin up the container manually each time a function is called.
Unfortunately, that would add a tremendous amount of processing overhead and make a function slow. To use EC2 at all you would need your instance to be already available and waiting for the triggering event, which means 100% instance usage per month. This is going to add a significant cost.
So here's the hard facts – I'm dipping into my pocket every week to the tune of… $7.40 for you guys to do 54M searches against a repository of half a billion passwords 🙂 pic.twitter.com/WPez1SXYmD
— Troy Hunt (@troyhunt) June 27, 2018
#2. Your functions aren’t going to run 100% of the time and that’s a backbone which is evident behind Lambda’s pricing model. Lambda works best around and below 3 million function executions per month (source) since you’d want to operate in the range where the free executions that come with Lambda still have a noticeable impact on your bill.
However, if your traffic starts getting ahead of 3 million, maybe its time to move to EC2. Before that, consider the next observation.
#3. If we observe entirely from the perspective of use cases, AWS Lambda and EC2 have very different implications. As discussed in the above point, AWS Lambda will be a perfect fit for low compute use cases such as serverless authentication, scheduled CRON jobs, chatbots, Alexa skills and more.
On the other hand, use cases which will need high compute resources such as real-time audio/video transforming, ETL jobs, etc; EC2 might be a better option. Concluding this, no one size fits all and hence tried and tested approach would be the most suitable.
— Cory O'Daniel (@coryodaniel) August 14, 2018
Amazon API Gateway Pricing
Amazon API Gateway charges you only for the APIs which are in use without any upfront fees. You only pay for the number of API calls you receive and the amount of data transferred and caching (if opted). Here’s how:
- Charges for API Calls: $3.50 per million API calls received.
- Data Transfer Costs: First 1 GB free then $0.09/GB for next 9.99 TB.
For example, a regional API received 5 million API calls per month and each API call returns responses of 3 KB in size without caching.
- Amazon API Gateway API Calls charge: 5 million * $3.5/million = $17.50
- Total size of data transfers: 3 KB * 5 million = 15 million/KB = 14.3 GB
- Data transfer charges: 14.3 GB * $0.09 = $1.29
- Total Amazon API Gateway charges: $17.5 + $1.29 = $18.79
The Significance of API Gateway in Serverless Apps
APIs imparts an added value to the serverless functions by facilitating normalize access points for system functions, including security and monitoring. Considering the event-driven architecture, APIs help functions bridge service modelling among the systems by acting as a http endpoints to trigger your functions.
API Gateway makes a collection of functions look like a single API developed to meet the specific application requirements. In other language, it consolidates the path to all of the system’s commonly used features in the form of an aggregated service.
This approach helps in tackling the load of security, orchestration and transformation of the microservices. It also works as a gateway to forward requests only which are authenticated and authorized.
Or as Marco Palladino, CTO at Mashape, explains, “API Gateways works as an abstraction layer that sits on the execution path of every requests that goes to one of your functions.” Saying this, API Gateway definitely plays a critical part of any serverless application, however, the cost implications are pretty high as we discuss about it in the next session.
Case Study: Calculating the Price of a Serverless Application
Serverless costs is more than pay-per-trigger. In this section, we will analyze the cost of running a demo serverless application and find out how much AWS Lambda and other services costs in actual.
As a demo app, we will be analyzing the Voting App. Here’s the architecture.
Let me walk you through the charges incurred for using the following services:
- API Gateway
- AWS Lambda
- Amazon S3
- CloudWatch Logs
- Network Data Transfer
To understand the working of the Voting App click here. The following app served almost 2 million requests per month. The free tier from all the services has been excluded and pricing are with context to US-EAST-1 region.
#1. API Gateway: The current API Gateway Pricing is $3.50 per million requests, plus data charges. Considering we have 1.5 GB of cache memory and 2 million requests/month, our total cost would be $34.36
#2. AWS Lambda: Since most of the compute work is focused on the 60 lines of code that two of our Lambda function executes, this is where I was expecting huge costing. However, it isn’t. Here we have 2 Lambda functions with 256 MB compute memory, serving 2 million requests/month.
Lambda function 1 executes at 400 ms and Lambda function 2 executes at 500 ms. The total cost will be Lambda Function 1 ($0.20) + Lambda Function 2 ($0.20) = $0.40
#3. DynamoDB: The DynamoDB pricing includes permanent free tier upto 25 write units and 25 read units. This means we don’t have any charges for that. The only cost that we will have to incur is of 1 GB Dataset with a strong data consistency. Hence, the overall cost will be $2.81
#4. Amazon S3: This will be storing our static content like HTML, CSS and Java. The S3 cost for standard storage of 1 GB would be $0.02
#5. CloudWatch Logs: The CloudWatch costs for the service coming from logs being sent to CloudWatch Logs and the storage of these logs. These logs are generated by the AWS Lambda function execution and by API Gateway execution. You can control how much logs you need to generate from AWS Lambda and hence optimize accordingly.
Our demo app ingests 200 MB of data everyday which is monitored over 3 parameters with archival of logs. All this comes down to 3 GB * $0.50 = $1.5 Plus, storage cost of $0.03/GB = $0.09 Hence, total cost = $1.59
What does Serverless really cost?
This all comes down to a monthly cost of $50.14 approximately. The striking thing that we observed is that there are more than just CPU & RAM. For most of the people opting for serverless, the major cost drivers would not be AWS Lambda but API Requests, storage and network transfers.
Where are the hidden costs?
#1. API Requests: As discussed in the previous section, it is obvious that our serverless apps are going to be API heavy and its significance is undeniable. This will cost your around $3.50 per million executions.
#2. Networking: If you’re sending data in/out, you need to carefully monitor the cost of this. At $0.50-$0.90 per GB-out and $0.1-$0.2 between VPCs/regions on AWS. This has high chances of getting really expensive.
#3. Code Maintenance: Serverless coding equals to more lines of code. For each new functionality added to the software system, the number of lines of each function needed to maintain the software’s functionality, grows at a steep linear rate. Since the shared code is an antipattern, each function has to have its own logic.
#4. Cold Starts: You may read more about it in our serverless performance blog. Since cold start increases the execution time it is directly proportional to the costing. Additionally, for a startup, an added latency of 100 ms can be a driving factor for users to adopt or discard the product.
3 Questions to Consider Before Jumping into Cost Optimization
#1. What is the contribution of AWS Lambda pricing to your total bill? Serverless applications consists of databases, storage, network costs, APIs, data processing systems to name a few. Considering the percentage of AWS Lambda cost to the overall application cost, you will have to see whether it is worth running cost optimization cycles or not.
#2. What is your app’s requirement in terms of the performance? Before iterating functions memory allocation for the sake of lower cost, consider this: memory allocation have a significant impact on the cold start and runtime, both of which are directly proportional to the cost. Hence, if your app requires low latency performance then opting for degraded performance at lower cost won’t be a recommended solution.
#3. Which and how many of your functions of your app are frequently used? Not every one of your functions will be invoked at the same frequency. Hence, focusing cost optimization for functions with high frequency is recommended, for example, functions having hundreds of thousands or millions number of invocations.
How to Monitor the Function for Cost Optimization?
AWS Lambda gives a fancy picture of a low cost solution and that is one of the primary reason behind it accelerated performance.
However, in spite of the developers keeping a keen eye on the maximum memory size limit and execution time, there are high chances of cost getting out of your control due to a variety of reasons. Some of them are DDoS attack, excess memory allocation or a simple bug in your code bundle.
This inevitable necessitates the requirement of monitoring function efficiently. Here are three basic ways you can get started:
#1. Manual Approach
Depending upon how many functions you have, this may take from minutes to hours. For example, every time your Lambda function is executed, a record prints:
Duration: 1000 ms Billed Duration: 500 ms Memory Size: 1024 MB Max Memory Used: 50 MB
The above record print clearly depicts that the function you’ve executed is just using 50MB out of 1024MB. In such cases, you can save money by allocating 128MB. If you go allocating less memory than this, you function might not execute at all.
Why development teams are attracted towards higher memory allotment is because more CPU means faster executions and potentially lower cost. Therefore a recommended solution would be to test and iterate your function’s execution time on different memory sizes.
This approach works perfect for the team with the fewer number of functions since monitoring them is easy. On the other hand, since this requires monitoring of functions on regular basis, this will take a considerable time if you have many functions.
#2. Cost Explorer
AWS Console provides AWS Cost Explorer through which you can monitor the pricing of various AWS services over a week, month and quarter. Further, you can classify it based on the region, usage type, tag name, etc.
If you have tagged your Lambda functions properly, this will ease your monitoring upto a great extent. You can tally the pricing of your Lambda functions and iterate the changes accordingly.
On the other hand, if you haven’t tagged your function properly, AWS Cost Explorer won’t help much. In such cases, what you can do is leverage CloudWatch Alarms to get a notification when a function exceeds the configured limit.
Despite the fact that it helps in monitoring the cost of Lambdas, it doesn’t give you the insight on what is actually wrong and where. This helps only in figuring out whether Lambda costs have increased or not whenever an issue occurs.
#3. 3rd Party Tools
There are many 3rd-party tools that can come in handy. These tools will help you indirectly with cost optimization by efficient and accurate monitoring of your AWS Lambda functions. Some of them are:
Tuning your executing time and memory size will save you a lot on computing resources and costs. Saying that, it is equally critical to keep a sharp eye on functions that can be optimized by tracking its cost in real time.
Strategies for AWS Lambda Cost Optimization
There are multiple combinations of usage and configuration that affects the overall pricing of Lambda functions. This can be problematic sometimes!
For example, if you’re working for a small startup, you definitely don’t want to spend $500 over a single Lambda function. Let alone having hundreds of them. Here are few strategies to help you keep your Lambda cost in control:
#1. Optimizing Function Frequency
There are various factors that affects the invocation frequency of Lambda function. This is based on the triggers. Closely monitor your triggers and see if you can do to reduce the number of invocations over the time.
For example, suppose your Lambda function is being triggered from the Kinesis Stream. Since the batch size is quite small, the invocation frequency is pretty high. In such cases, what you can do is opt for higher batch size so that your Lambda function is invoked less frequently.
#2. Writing Efficient Code
Well, the function that executes in half the time is a function that will cost you half the money. One must note that the execution duration is directly proportional to the amount of money you’ll be charged. Saying that, it is critical to keep an eye on the Duration metric inside the CloudWatch. And it’d be a common sense to modify and iterate your function if it is taking suspiciously long time to execute.
For this purpose, you AWS X-Ray can help you monitor function from end to end.
#3. Monitoring Data Transfer
While talking about Lambda charges, often times it gets out of our sight that you’ll also be charged for the data transfer at standard EC2 data transfer rates. Hence, it is default to keep an eye on the amount of data you’re transferring out to the internet and other regions of AWS.
While talking about internal data transfer, there isn’t much you can do about it as you can’t control the amount of data your Lambda will transfer. Likewise, there is no metric inside CloudWatch which can help you in monitoring the data transfer rate.
In such cases, here’s what you can do:
- Keenly monitor your AWS Cost & Usage Report. Filter it by Resource (your Lambda function) and find different values in the Transfer Type column. Further, get the usage amount. This might come off as slightly time consuming.
- Log the size of data transfer operations in your Lambda code and then configure a CloudWatch Metric Filter as a reference that becomes a CloudWatch Metric.
#4. Developing In-house Tools
If all of the above options aren’t suitable for you and you need a concrete solution that actually works, you can opt for developing in-house tools. Here are some of the examples:
- Real-time Lambda Price Calculator: This is a quick and automated way to monitor estimated monthly cost in real-time of AWS Lambda based on your current usage. For more information, you can look here.
- Memory Metric Filter: This is a simple CloudWatch Logs Metric Filter that can help you in monitoring by extracting memory size and allocated memory from the execution records. Launch Stack here and get started.
All that being said, one thing is for sure, mapping out your requirements and how much it will cost to bring your idea into reality, is the first step towards getting started with serverless architecture. No one size fits all! For some organizations, serverless is helping in cutting down cost with a huge margin while others are probably looking for more comprehensive options considering the hidden costs of serverless.
Though the notable thing is every serverless provider offers you free tiers which can be sufficient for you for the time being provided you have a smaller workload. Ultimately, serverless offers a huge potential in cost and time saving if done right.
To avoid any surprises, it’d be better to deep dive and analyze the potential of your serverless application. I’d love to hear what has been your experience with serverless costs. Drop me an email at firstname.lastname@example.org or connect with me on Twitter @RohitAkiwatkar