Alix Akhribi
June 2 2023
To stand out in the global competition, wholesale and retail companies need to tap into process and customer data and think about the value they can extract from analytics.
For manufacturers, true digital transformation starts by envisioning where in the value chain can data be applied to make a difference.
All public sector services should be designed to serve citizens first. Digital solutions and applications must be easy to use, despite physical and cognitive disabilities.
Digital processes and data-led services help energy and utility sector companies develop a stable energy offering with transparent, customer-centric services.
Shared platforms offer fast entry to new markets, cost-efficiently and scalably. But lasting value add comes from cross-industry collaboration and linking products with complimentary services.
Digitally disrupted, the companies in the banking, finance and insurance sector must actively innovate new approaches to build omnichannel customer experiences that fully utilize data.
While medical device software is strictly regulated, there's room for innovations that make life easier for patients and caregivers. Stable and secure data flow is a must.
June 2 2023
In this blog post, we will dive deep into using AWS Lambda Power Tuning to optimize your Lambda functions for cost and performance. As serverless architectures continue to gain traction, the need to maximize the efficiency of Lambda functions is becoming more critical than ever. This tool helps developers find the optimal balance between performance and cost for their use case. By the end of this post, you will better understand how to use Lambda Power Tuning to find the best memory setting for your Lambda functions.
AWS Lambda is an event-driven, serverless computing platform provided by Amazon Web Services (AWS). It allows developers to run their code without managing servers, automatically scaling the compute capacity based on the workload. However, as applications grow, so do the costs and performance requirements. Finding the optimal balance between cost and performance can be challenging.
Disclaimer: Please note that following this tutorial may incur costs for AWS services, particularly AWS Lambda and AWS Step Functions. The charges will depend on the number of invocations, memory settings, execution time, and the duration of the step function executions. Review the AWS Lambda pricing and AWS Step Functions pricing before proceeding with the tutorial. Additionally, remember to delete or disable any resources you no longer need after completing the tutorial to avoid incurring ongoing costs.
Lambda functions are billed based on the memory and compute time used during execution. Higher memory settings result in faster execution times but at a higher cost per invocation. Conversely, lower memory settings reduce costs but can lead to longer execution times. This trade-off creates a dilemma for developers: how to find the optimal balance between cost and performance?
AWS Lambda Power Tuning is an open-source tool that addresses this problem by systematically finding the best memory configuration for a given Lambda function. The tool allows developers to quickly and easily analyze various memory settings' cost and performance implications, helping them make informed decisions about their function's configuration.
There are multiple ways to deploy AWS Lambda Power Tuning:
You can find all the tutorials for deploying the application here. The easiest way to start with Lambda Power Tuning is by using the Power Tuning Serverless Application.
To deploy the AWS Lambda Power Tuning Serverless Application:
The CloudFormation template will create the necessary resources, including the step function.
The input parameters for the step function include:
lambdaARN
: The Amazon Resource Name (ARN) of your Lambda functionpowerValues
: The memory settings you want to testnum
: The number of invocations for each memory power valuepayload
: The input payload for the Lambda functionparallelInvocation
: Whether to use parallel invocations (true is recommended)strategy
: The optimization strategy (cost, balanced, or speed)Note: To minimize the cost, you can adjust the number of invocations (num
) and the power values (powerValues
) you use when testing your Lambda function with the Power Tuning tool.
In this section, we will create a simple CPU-heavy Lambda function using JavaScript as an example to demonstrate the power of AWS Lambda Power Tuning. We will use a naive Fibonacci algorithm, which is computationally expensive, to show how the Power Tuning tool can help optimize the cost and performance of such functions.
While there are more efficient algorithms and techniques to calculate Fibonacci numbers, such as memoization and matrix exponentiation, we will keep the example simple to focus on the AWS Lambda Power Tuning process. Using a naive approach, we can highlight the potential performance gains and cost savings the Power Tuning tool can provide.
Here's the naive Fibonacci algorithm implemented as an AWS Lambda function in JavaScript:
const fibonacci = (number) => {
// Check if number is a positive integer
if (!Number.isInteger(number) || number < 0) {
// If not, throw an error with a helpful message
throw new Error('Invalid input. Please provide a positive integer.');
}
// Base case: return the number if it's 0 or 1
if (number <= 1) {
return number;
}
// Recursive case: return the sum of the previous two numbers in the sequence
return fibonacci(number - 1) + fibonacci(number - 2);
};
exports.handler = async (event) => {
try {
// Extract the value of 'number' from the event object
const { number } = event;
// Call the Fibonacci function to calculate the result
const fibonacciResult = fibonacci(number);
// Return the result as a JSON object with a 200 status code
return {
statusCode: 200,
body: JSON.stringify({ fibonacciResult }),
};
} catch (error) {
// If there was an error, return a 400 status code and the error message
return {
statusCode: 400,
body: error.message,
};
}
};
After creating this Lambda function, you can use its Amazon Resource Name (ARN) as input for the AWS Lambda Power Tuning tool.
Once the Power Tuning Serverless Application is deployed, you can configure and run the step function to test different memory settings for your Lambda function. Follow these steps:
{
"lambdaARN": "arn:aws:lambda:us-east-1:123456789012:function:your-function-name",
"powerValues": [128, 256, 512, 1024, 1536, 3008],
"num": 20,
"payload": "{\\"number\\": 35}",
"parallelInvocation": true,
"strategy": "cost"
}
Click the "Start execution" button again, and the step function will invoke your Lambda function with the specified memory settings and gather data on execution time and cost.
After the step function has completed its execution, you can visualize the results by examining the generated graph. This graph shows the relationship between the execution time and cost for each tested memory setting.
To view the graph:
The graph will help you determine the best memory setting for your Lambda function, taking both cost and performance into account. You should run the step function with different memory settings to refine your understanding of the trade-offs.
After completing the tutorial, cleaning up the resources created by the CloudFormation template is essential to avoid incurring ongoing costs. The cleanup process will remove all the resources associated with the AWS Lambda Power Tuning Serverless Application, including the Step Functions state machine, Lambda functions, and IAM roles.
To delete the resources, follow these steps:
By performing these steps, you will remove the resources associated with the AWS Lambda Power Tuning Serverless Application and prevent further costs. Remember to review your other AWS resources, such as the Lambda functions you tested, and disable or delete them if they are no longer needed. Regularly reviewing your AWS resources and removing unnecessary ones will help you maintain a cost-effective and efficient infrastructure.
AWS Lambda Power Tuning is a valuable tool for optimizing your Lambda functions in terms of cost and performance. By creating a CPU-heavy Lambda function, deploying the Power Tuning Serverless Application, configuring and running the step function, and visualizing the results, you can make data-driven decisions about the memory configuration for your Lambda functions. This optimization process will enable you to strike the right balance between cost and performance, allowing you to get the most out of your serverless architecture.
Remember that every Lambda function is unique, and the best memory setting for one function may not be the best for another. Regularly reviewing and optimizing your Lambda functions using AWS Lambda Power Tuning will ensure that your serverless applications remain efficient and cost-effective over time.
In this bonus section, you'll learn how to optimize your Lambda function further by converting the original JavaScript code to TypeScript and minifying it using ESBuild. It is important to note that since our current function isn't that large, we won't see a significant size reduction or necessarily improved performance. However, this bonus section is included to give interested readers an insight into further optimization possibilities and how to use TypeScript with AWS Lambda.
Although it's not necessary to convert the code to TypeScript first to minify it, I want to cover how to use TypeScript for Lambda functions. As of writing this, AWS Lambda only supports Node.js and doesn't support TypeScript natively. By minifying the code, you can reduce its size and potentially improve the Lambda function's performance.
There are other ways to use ESBuild, such as using it with AWS CDK, but this blog post aims to demonstrate the possibilities using the simplest approach, making it easier to follow.
Here's the original JavaScript code for the Fibonacci Lambda function, converted to TypeScript:
interface LambdaEvent {
number: number;
}
interface LambdaResponse {
statusCode: number;
body: string;
}
const fibonacci = (number: number): number => {
// Check if number is a positive integer
if (!Number.isInteger(number) || number < 0) {
// If not, throw an error with a helpful message
throw new Error('Invalid input. Please provide a positive integer.');
}
// Base case: return the number if it's 0 or 1
if (number <= 1) {
return number;
}
// Recursive case: return the sum of the previous two numbers in the sequence
return fibonacci(number - 1) + fibonacci(number - 2);
};
export const handler = async (event: LambdaEvent): Promise<LambdaResponse> => {
try {
// Extract the value of 'number' from the event object
const { number } = event;
// Call the Fibonacci function to calculate the result
const fibonacciResult = fibonacci(number);
// Return the result as a JSON object with a 200 status code
return {
statusCode: 200,
body: JSON.stringify({ fibonacciResult }),
};
} catch (error) {
// If there was an error, return a 400 status code and the error message
return {
statusCode: 400,
body: error.message,
};
}
};
Install ESBuild as a development dependency: In your project directory, run the following command to install ESBuild:
npm install esbuild --save-dev
Create a TypeScript file: Create a TypeScript file called lambda.ts in your project directory and paste the TypeScript code provided above.
Run the npx command to minify the TypeScript code: In your project directory, run the following npx command to minify the TypeScript code and generate a JavaScript file:
npx esbuild lambda.ts --minify --platform=node --target=node18 --outfile=lambda.min.js
This command does the following:
-minify
: Minifies the output file by removing unnecessary characters and renaming variables.-platform=node
: Sets the platform to Node.js.-target=node18
: Specifies the target Node.js version (Node.js 18.x in this case), ensuring compatibility with the AWS Lambda runtime.-outfile=lambda.min.js
: Defines the output file name.After running this command, you will have a minified JavaScript file named lambda.min.js
containing the minified and bundled version of the TypeScript code. This file can be deployed as your Lambda function.
Now that you have successfully minified your Lambda function, it's time to update your function with the lambda.min.js
code and compare the results.
In the image above, you can see the difference in size between the original Lambda function and the minified version. The original function was 624.0 bytes, while the minified function is now only 586.0 bytes. Admittedly, the 6.09% reduction in size may not seem significant, but it's important to remember that our Lambda function was quite small to begin with.
For larger Lambda functions, employing optimization techniques like this can have a more substantial impact on reducing the function size depending on the complexity and length of the code. Smaller function sizes can lead to faster cold starts and potentially better performance as unnecessary code is removed during the minification process.
Using the same steps you took before Invoke your Lambda function using the AWS Lambda Power Tuning, use same test event and configuration as before. Take note of the execution time, memory consumption, and any other relevant performance metrics.
Compare the results of the minified Lambda function to the original version. Pay close attention to any improvements in cold start times, overall execution time, and memory usage.
In the performance comparison above, you can see that even though the minified Lambda function has a relatively small 6.09% reduction in file size, it still made a noticeable 4% difference in cost and execution time compared to the original version. This demonstrates that even minor optimizations can yield cost savings and performance improvements.
For larger Lambda functions, employing optimization techniques like this can have an even more substantial impact on reducing the function size, depending on the complexity and length of the code. Smaller function sizes can lead to faster cold starts and better performance as unnecessary code is removed during the minification process. In addition, reducing execution time and memory usage can contribute to lower costs when running your Lambda functions.
By following this bonus section, you have learned how to optimize your AWS Lambda function using TypeScript and ESBuild and gained insight into using TypeScript for Lambda functions, which AWS Lambda doesn't natively support. You have also explored the potential benefits of these techniques when applied to larger Lambda functions.
Ready to build something great? Our 15 years of experience mean we can handle any idea, big or small.