When using a serverless cloud architecture based on AWS Lambda functions, it is crucial to define and set the optimal parameters for the functions to run efficiently and without latency at initialization, also called Cold Start.
A cold start in serverless architecture occurs when an inactive function is executed for the first time. This happens because the cloud service provider must provide the resources for the runtime container and then run the function.
Cold starts hurt the response of the systems, and this causes end-users to perceive that the system is slow due to the long loading times implied by a Cold Start, since a simple request to an endpoint or a database can take between 3s to more than 10s to load, at the end of the Cold Start the system loads efficiently so the response can take only microseconds.
However, in most cases, the cold start generates a great inconvenience because the first impression always counts, even more so when it takes so long.
What can we check to identify a cold start in serverless architecture?
We will review the factors influencing a cold start in serverless architechture, e.g., runtime language, package size, lambda memory size, and VPC configuration.
Runtime
So, let’s review the language of the runtime and the memory size of the lambda function. This analysis is taken from references from a couple of sources; it is important because each programming language has faster startup times than others, and the memory size defined for the lambda function affects the provisioning necessary for executing the function.
The following graph compares the cold start times of the following languages: Java, Graalvm, .Net, Go, Rust, Python, NodeJS, and Ruby.
The startup time is also evaluated by comparing it with different memory sizes of the lambda function.
Which language to choose?
Derived from the graph, we can see that the languages that have a better performance against cold start are Python, Rust, Go, NodeJS, and Ruby, and the optimal memory size for the lambda function in the cost-benefit ratio is 1024MB where the languages that stand out for having a good performance are Python, Rust and Go.
Package Size
Another factor that significantly affects the size of the function deployment package is the size of the function deployment package. Large packages require a longer time for downloading and decompression, so it is advisable to keep the size of the function deployment package as small as possible.
Optimization with Layers
It is advisable to remove unnecessary dependencies and keep them up to date; an excellent strategy to keep the package size small is to use the layers of the Lambdas functions to keep the deployment package small and the dependencies in the layers.
VPCs?
One of the most significant factors affecting Cold Starts was if the lambda function was configured inside a VPC, which could add up to 3 additional seconds to the load. This changed incrementally in 2019 when AWS Announced improved VPC networking for AWS Lambda functions, and cold starts were significantly reduced.
VPC can be optimized
We can still follow some recommendations in VPCs, such as configuring the VPC to define the use of AWS resources through Amazon VPC interface endpoints instead of configuring it from internet access.
My architecture is already defined. How can I identify the improvements I can apply to prevent cold starts?
Considering the previous points, we can evaluate different architectures of lambda functions to create serverless functions that reduce and minimize the cold start. For the case of architectures already defined, we can apply other monitoring methods to identify cold start times and see what areas we can optimize to reduce latency.
For example, we can define the AWS X-Ray service to obtain load time metrics.
We can use x-ray to get an overview of the cold starts
In the following case, we can see how X-Ray shows a general breakdown of the load times in a lambda function, the initialization time, invocation, and access to services, in this case, S3.
By having a record of how the performance and latency of our functions is affected, we can apply the recommendations according to our infrastructure and measure the latency of the different phases of the functions.
Conclusions
It is essential to monitor the performance of the functions and services used in our infrastructure to have functional applications with high availability and performance.
Continuous monitoring is fundamental to maintaining optimized lambda functions, so it should be adopted as an ongoing process.
There are different ways of recording the performance of lambda functions. Do you know of any tools? Do you know of other best practices and recommendations to apply?
Want further reading? Some useful links: