AWS recently launched support for Graviton2 in Lambda, with a promising boost in price to performance. Based on the specs, GB-seconds price is 20% cheaper for Lambda Functions powered by AWS Graviton2 vs existing x86-based functions. Depending on the workloads, the performance of ARM can be substantially better (see x86 vs ARM @ Anandtech), which could also result in a reduction in execution time/response time for Lambda Functions. Customers should test to see the price to performance increase but consider up to 34% improvement.
What do you have to do to move your Lambda functions to AWS Graviton2, and how real is the price to performance gain?
The change is as simple as re-deploying the Lambda Function under a new version with the new architecture flag enabled. This is an optional parameter that has been introduced by AWS, and it defaults to x86_64.
Note: At launch time, runtimes that are available include Python 3.8 and 3.9, Node 12 & 14, Java 8 and 11, Ruby 2.7, OCI, .Net core 3.1, and custom runtime. We expect this list to grow over time.
Testing and compatibility will require more diligence. Depending on your workloads, you likely have three scenarios for migrating your Lambda Functions to Arm.
- Scripted languages: Your Lambda Function code will be compatible as long as the run time is supported, but you are likely using a number of external libraries. To find out if your libraries are supported or not, the first step is to launch your Lambda Function on Arm. If the launch is successful, then your libraries are at least available for Arm. Each library needs to be evaluated for support, and in most cases, you can compile the libraries on Arm and create a Layer to make them available to the Lambda function. Once you verify the required libraries are available, you need to adjust the Architecture in the Lambda Runtime configuration.
- Java Bytecodes: That’s the case of the JVM. It should be only a matter of dropping the compiled package into the application server. If there are no native libraries, that should be all.
- Binaries: such as Go, or C++. It’s required to recompile binaries and all the dependencies with the latest compilers supporting Arm.
We tested it on our own infrastructure.
Cloudwiry product is implemented itself in cloud-native technologies. The vast majority of the compute layer is implemented through Lambda functions, so we picked one of our more expensive Lambda functions and migrated to Arm. The process was pretty straightforward. Just click the “Runtime settings” in the console.
Then, select Architecture arm64.
We migrated one of our heaviest functions, and we did not observe any performance difference.
In our case, this Lambda Function is a collector process that executes a significant number of API calls.Net Input/Output is significant, and probably the worst-case scenario to see the advantages of the AWS Lambda Function powered by Graviton2. Since the function is not CPU heavy, the performance is similar, which means a price decrease.
How to Identify Blockers
Unfortunately, there is no silver bullet for it, but there are a few bits of advice. In the case of Python dependencies, one of the most common issues is the unavailability of the package for the aarch64 (Arm) platform. The PyPi site, which contains the most comprehensive index of packages, doesn’t include the support status for the different architectures (in our case, we should look for aarch64).
The following repository contains interesting information about support for Graviton2 in Python: aws-graviton-getting-started/python.md at main · aws/aws-graviton-getting-started (github.com)
The good news is that testing it is actually quite simple: launch a t4g.nano instance with Amazon Linux 2 and try to load the requirements.txt (or the specific package under test).
|$ pip3 install tensorflow -t ./tmp
ERROR: Could not find a version that satisfies the requirement tensorflow (from versions: none)
ERROR: No matching distribution found for tensorflow
To check multiple packages, it’s possible to use the requirements.txt
|$ pip3 install -r requirements.txt -t ./tmp|
For Java, the process could be more complicated. The detection of non-standard shared libraries inside the jar files could be a good indicator that there is a native library involved. More information can be found in this StackOverflow question.
In our case, we found a blocker in some other functions from another module using Pandas, taking 20 minutes to compile as it’s not available in binary format yet for Graviton2. The solution is to precompile it and ship it into a Lambda function layer.
In this article, we have discovered how to take advantage of Arm architecture for one of our favorite services: AWS Lambda Functions. We tested it and described what should be considered to assess the migration. We already have talked about Graviton2 previously at AWS Graviton2 for Non-EC2 Services and AWS Graviton2: Arm on Cloud blog articles.