Rightsizing Your Lambdas: Lambda Power Tuning & Compute

Vaibhav Malhotra
SSENSE-TECH
Published in
9 min readApr 26, 2024

--

With Lambdas, time is money.

While cloud computing and serverless technology have revolutionized the way we approach and operate our infrastructure, they also come with their own set of challenges, particularly in terms of cost management.

To effectively be cost-conscious, we need to understand how each element or resource contributes to the cost and responsibly, and find ways to optimize them. In this article, I will explore two tools available from AWS that can directly impact both the bottom line and performance.

Let’s dive into how I achieved 61% performance improvement while reducing the cost for a Lambda by 25%, with a relatively low effort by leveraging the Lambda Power Tuning and Cost Optimizer.

Understanding How Lambda Pricing Works

When it comes to the cost of your Lambda function, there are three key factors to consider:

  1. Number of executions: You pay per execution, with a cost of $2E-7 per execution or $0.20 per million executions.
  2. Time per execution: Longer execution times incur higher costs. This incentivizes efficient code writing for faster performance. Billing occurs in 100ms increments, with a maximum function timeout of 5 minutes.
  3. Allocated memory: When creating a Lambda function, you allocate memory to it, ranging from 128 MB to 1,536 MB. Allocating more memory than needed will lead to unnecessary charges, while not allocating enough memory will cause the execution to fail. Thus, finding the optimal memory configuration is crucial for successful and cost-effective executions.

The total cost of Lambda is a combination of the time taken for each execution and the memory allocated to it.

This is where our first tool, AWS Lambda Power Tuning, comes into play.

AWS Lambda Power Tuning

AWS Lambda Power Tuning is an open-source tool that uses AWS Step Functions to help you optimize your Lambda functions for either cost savings or improved performance.

This easy-to-deploy tool is fast to execute and supports any language. By analyzing execution logs, it suggests the best power configuration to minimize costs and maximize performance. It also supports cross-region invocations and parallel execution for fast results.

Simply input a Lambda function ARN, and the state machine will invoke that function with various power configurations, ranging from 128 MB to 10 GB — the choice is yours. It will then analyze all the execution logs and propose the optimal power configuration.

You can also visualize and fine-tune the memory/power configuration of Lambda functions. An example of Lambda Power Tuning results is illustrated below:

Example of Lambda Power Tuning results

The tuner generates a visualization of the average cost and speed for each power configuration. Depending on your specific use case, you can tailor the optimization accordingly.

For instance, if your priority is execution time, opting for 1536 MB may be preferable despite higher costs. Conversely, if cost efficiency is paramount, 256 MB appears to be the optimal choice.

Ideally, you will strike an optimal balance between both, which in our example would be around 1,024 MB.

How To Use Power Tuning

Drill down on the state machine name, click “Start execution,” and you will be prompted to enter input values for this execution in the following format:

{
"lambdaARN": "arn:aws:lambda:<AWS_REGION>:<ACCOUNT_ID>:function:<FUNCTION_NAME>",
"powerValues": [
128,
256,
512,
1024,
1536,
2048,
3008
],
"num": 30,
"payload": {
"key1": "value1",
},
"parallelInvocation": true,
"strategy": "balanced"
}
  • lambdaARN: the ARN of your lambda function you want to tune.
  • powerValues: a list of power values between 128MB and 3008MB.
  • num: the number of invocations for each power configuration (minimum 5, recommended: between 10 and 100).
  • payload: the JSON payload for your function.
  • strategy: it can be "cost", "speed", or "balanced", which is pretty self-explanatory

That’s it! Once the input is finalized, you can kick off the execution and visually inspect each step in the state machine as it executes.

Analyze the output

To view the result of the execution, click on the “Execution input and output” tab. A sample output looks like the following:

{
"power": 256,
"cost": 1.3020000000000001e-7,
"duration": 30.91388888888889,
"stateMachine": {
"executionCost": 0.00033,
"lambdaCost": 0.00013721505,
"visualization": "https://lambda-power-tuning.show/#<encoded_data>"
}
}
  • power: the optimal power configuration (RAM)
  • cost: the corresponding average cost (per invocation)
  • duration: the corresponding average duration (per invocation)
  • stateMachine.executionCost: the AWS Step Functions cost corresponding to this state machine execution
  • stateMachine.lambdaCost: the AWS Lambda cost corresponding to this state machine execution
  • stateMachine.visualization: if you visit this autogenerated URL, you can visualize and inspect average statistics about cost and performance
Power Tuning result visualization

Let’s analyze the previous visualization. If the memory allocation is increased from 128 MB to 256 MB, there is a significant reduction in invocation time, plummeting from 81ms to 31ms. Concurrently, the invocation cost experienced a slight decrease from $0.000000172 to $0.00000013.

Based on these findings, it is evident that 256MB emerges as the best memory allocation, striking a balance between minimizing costs and ensuring invocation time remains competitively low compared to other memory configurations.

Using weighted payloads

In the scenarios where the payload of Lambda impacts the performance or speed, incorporating multiple payloads in the tuning process allows for comprehensive optimization.

Additionally, weighted payloads are advantageous for functions with side effects, particularly those that are challenging or impossible to test with a single payload.

To configure weighted payloads in step function input, use the following format:

{

"num": 100,
"payload": [
{ "payload": {…}, "weight": 10 },
{ "payload": {…}, "weight": 15 },
{ "payload": {…}, "weight": 25 },
{ "payload": {…}, "weight": 50 }
]
}

In the example above, the weights 10,15, 25, and 50 are relative weights. They correspond to 10% (10 out of 100), 15% (15 out of 100), 25%(25 out of 100), and 50% (50 out of 100) respectively — meaning that the corresponding payload will be used 10%, 15%, 25% and 50% of the time.

For example, if num=100 the first payload will be used 10 times, the second 15 times, the third 25 times, and the fourth 50 times.

Note: Ensure that the number of weighted payloads is equal to or less than the specified ‘num’ value. For instance, if you have 50 weighted payloads, the ‘num’ value should be set to at least 50 to ensure that each payload is utilized at least once.

Power Tuning in CI pipeline

Very cool! Now that we understand all the steps involved in tuning our Lambda functions with this tool, we can also automate the Lambda tuning in our CI/CD pipeline.

Power tuning seamlessly integrates into your team’s CI pipeline. Developers can enable a flag to initiate power tuning for a Lambda function. This action will trigger the AWS power tuning step function, generating a visualization URL. Developers can then analyze this visualization to determine the optimal memory configuration. Once decided, the new configuration will be deployed alongside the Lambda function changes.

If you can standardize the deployment and CI tools used, you can further automate the process.

For example:

  • Parse the serverless.yml to extract the function names so they don’t have to be hardcoded.
  • Auto-generate the payload based on the configured event source for each of the functions.
  • Create an organization-wide CLI that lets you bootstrap new projects.

While Lambda Power Tuning is useful, it is typically done once or, if integrated into your CI/CD pipeline, triggered only when a Lambda function changes.

What if there was a way to obtain similar information based on live traffic? This would help us understand better and tune it further based on the (new) reality.

Well, AWS Compute Optimize to the rescue!

AWS Compute Optimizer

AWS Compute Optimizer is a powerful tool designed to help optimize your AWS environment. It provides insightful recommendations for optimizing AWS resources, leading to enhanced performance and cost savings.

Compute optimizer employs machine learning algorithms to recommend optimal configurations. Compute optimizer is available on all AWS accounts regardless of support level and is free of charge.

You can optimize 4 types of AWS resources:

  • AWS Lambda functions
  • Amazon Elastic Compute Cloud (EC2) instance types
  • Amazon Elastic Block Store (EBS) volumes
  • Amazon Elastic Container Service (ECS) services on AWS Fargate

Compute Optimizer Dashboard

While you are browsing the options, the interface will show you what the performance would have looked like over the past 2 weeks if you were running on the selected instance size instead of the current instance size.

The dashboard looks like this:

Firstly we are given an overview of cost optimizations for the account, which is followed by an overview of performance optimization.

Cost optimization can be translated to over-provisioned resources, meaning the Lambda is not fully utilizing the memory configured to it. Hence, we can reduce the memory configuration of the Lambda to a more optimal level and thereby save on cost.

Likewise, performance optimization can be translated to under-provisioned resources, meaning optimal instance size for resources can lead to better performance.

Improve performance: Memory under-provisioned || Save cost: Memory over-provisioned

Viewing Recommendations

You can navigate to View Recommendations to access recommendations for Lambda functions in your account. You can also filter these recommendations based on tags such as applications or teams.

You can also filter by Finding reason, where you can choose from Memory over-provisioned or Memory under-provisioned.

Memory over-provisioned
Examples of under-provisioned Memory

We can see the Recommended configured memory as well as the expected cost impact range for the change. For over-provisioned resources, we can also see the Estimated Monthly savings for recommended memory configuration.

As Compute Optimizer is passive and continuously leverages real-life traffic to provide its recommendations, we can utilize this tool to identify resource needs for different traffic patterns such as peak periods or lower traffic periods, as the memory requirements for these periods could be different.

Leveraging the Right Tool at the Right Time

Lambda Power Tuning is a great tool for optimizing resources during the development phase. You can optimize your resources before deploying them live, for both performance or cost depending on the use case. By integrating Lambda Power Tuning into our CI pipelines, we can save development time and help optimize our Lambdas across the stack.

Once your resources are live, the AWS Compute Optimizer comes into play to provide further optimization opportunities. This tool is passive and continuously provides feedback based on live traffic for the last two weeks. Best of all, the Compute Optimizer is completely free of cost and a great tool for detecting aspects we could have otherwise missed.

References

Editorial reviews by Catherine Heim, Luba Mikhnovsky & Mario Bittencourt.

Want to work with us? Click here to see all open positions at SSENSE!

--

--