AWS Lambda has become a popular choice for serverless computing due to its scalability and cost-effectiveness. Developers often face a dilemma when choosing the right programming language for their Lambda functions, especially when performance and cost are critical. In this blog post, we’ll dive into a benchmarking comparison of AWS Lambda functions written in Node.js, Go, and Rust. Each Lambda function performs a simple task: parsing a JSON object with a single field and returning a greeting message.
The Task
The task for each Lambda function is straightforward:
-
Parse the following JSON object:
{ "name": "Nebojsa" }
-
Return the greeting:
"Hello, Nebojsa"
While the task is simple, the performance implications can vary significantly depending on the language used. We will evaluate the performance based on key metrics such as execution duration, memory usage, and initialization time.
Benchmark Results
Let’s take a look at the performance metrics gathered during the benchmarking tests for each language.
Node.js Lambda
REPORT RequestId: 3f5846e1-9725-412c-9a5e-9d91d8804ccd Duration: 51.90 ms Billed Duration: 52 ms Memory Size: 128 MB Max Memory Used: 64 MB Init Duration: 132.71 ms
REPORT RequestId: 2ab7ddf0-3296-46f1-a958-2761af3b45ce Duration: 9.26 ms Billed Duration: 10 ms Memory Size: 128 MB Max Memory Used: 64 MB
REPORT RequestId: 28b97c26-47ff-4383-9833-a294313d59a9 Duration: 2.05 ms Billed Duration: 3 ms Memory Size: 128 MB Max Memory Used: 64 MB
REPORT RequestId: 1c0cd0af-5df1-443a-9f28-995a4737d868 Duration: 38.29 ms Billed Duration: 39 ms Memory Size: 128 MB Max Memory Used: 64 MB
REPORT RequestId: 843fe901-5616-4583-95d3-585ecfe5590c Duration: 2.28 ms Billed Duration: 3 ms Memory Size: 128 MB Max Memory Used: 64 MB
- Average Execution Duration: ~20 ms
- Memory Usage: 64 MB
- Initialization Duration: 132.71 ms (cold start)
Go Lambda
REPORT RequestId: a1eff6f3-2296-434d-ba4a-b3594c0cf50a Duration: 1.65 ms Billed Duration: 42 ms Memory Size: 128 MB Max Memory Used: 15 MB Init Duration: 39.67 ms
REPORT RequestId: 469b5c9f-2b57-4d68-a1fc-715c3d0b081a Duration: 1.20 ms Billed Duration: 2 ms Memory Size: 128 MB Max Memory Used: 16 MB
REPORT RequestId: ad0fed4c-8e10-46d0-ac63-58cd69157dc2 Duration: 1.29 ms Billed Duration: 2 ms Memory Size: 128 MB Max Memory Used: 16 MB
REPORT RequestId: 870e52a4-8402-43d9-98ba-7affd46dd212 Duration: 1.36 ms Billed Duration: 2 ms Memory Size: 128 MB Max Memory Used: 16 MB
REPORT RequestId: 7a0a8363-2084-47c8-aa76-a3dc51c4eb45 Duration: 1.18 ms Billed Duration: 2 ms Memory Size: 128 MB Max Memory Used: 16 MB
- Average Execution Duration: ~1.34 ms
- Memory Usage: 16 MB
- Initialization Duration: 39.67 ms (cold start)
Rust Lambda
REPORT RequestId: 8a3e23c7-1dea-4149-9642-5e77ff4c907a Duration: 1.63 ms Billed Duration: 23 ms Memory Size: 128 MB Max Memory Used: 15 MB Init Duration: 20.86 ms
REPORT RequestId: 039d7e26-1ab2-4478-895a-b4f9c4b1d0b3 Duration: 0.96 ms Billed Duration: 1 ms Memory Size: 128 MB Max Memory Used: 15 MB
REPORT RequestId: ab87210a-290a-43ad-9a29-a319dbcfbb7d Duration: 1.02 ms Billed Duration: 2 ms Memory Size: 128 MB Max Memory Used: 16 MB
REPORT RequestId: ca7db28e-227c-484a-bc74-89d91f1f959a Duration: 1.01 ms Billed Duration: 2 ms Memory Size: 128 MB Max Memory Used: 15 MB
REPORT RequestId: 3c177e67-bedd-4b85-99d9-4c88653610ed Duration: 0.96 ms Billed Duration: 1 ms Memory Size: 128 MB Max Memory Used: 15 MB
- Average Execution Duration: ~1.12 ms
- Memory Usage: 15-16 MB
- Initialization Duration: 20.86 ms (cold start)
Analysis
Execution Speed
Rust and Go significantly outperformed Node.js. Rust had an average execution time of about 1.12 ms, closely followed by Go at 1.34 ms. Node.js was slower, averaging around 20 ms. Rust’s performance makes it highly suitable for low-latency, performance-critical applications.
Memory Usage
Rust was the most memory-efficient, using 15-16 MB, slightly better than Go’s 16 MB and significantly better than Node.js’s 64 MB. This can be crucial in scenarios where optimizing for cost is essential.
Cold Start Time
Rust also had the fastest cold start time at 20.86 ms, making it ideal for applications that need to scale quickly during load spikes. Go was slower at 39.67 ms, and Node.js was the slowest at 132.71 ms.
Conclusion
Rust stands out as the top choice for AWS Lambda functions, delivering exceptional performance with the fastest execution times, lowest memory usage, and quickest cold starts. If your application demands high performance and efficiency, Rust should be your go-to language.
Go also performs admirably, making it a strong contender, especially if you’re looking for a balance between speed and ease of use. Node.js, while lagging in performance metrics, remains a viable option for developers who value its rich ecosystem and familiar JavaScript environment.
Ultimately, if maximizing Lambda performance is your priority, Rust offers the best results. For a more balanced approach with a slightly easier learning curve, Go is an excellent alternative. Node.js is best suited for scenarios where developer familiarity and ecosystem support outweigh the need for raw speed and efficiency.