Before we dive into the nitty gritty, let's define some AWS Lambda terminology. Feel free to skip to the next post and come back to it later if need be.
AWS Lambda
This is the name of the AWS service that allows us to run code in a serverless manner. That means, we don't have to think about servers, virtual or physical. No need to worry about backups, patching, or maintenance time (woohoo!).
Lambda Function
This the definition of our deployment. It contains configuration options and a zip package with our code. However, this is not running code, just the definition for it.
Lambda Execution Environment
This is a runnable instance of our code that has been deployed into a secure, isolated runtime environment using the configuration of our Lambda Function. Additional execution environments get created as requests come in and we need more capacity to handle them. AWS Lambda will create them as needed and shut them down when they idle for too long. We can have one execution environment, 100s of them, or none. All managed automatically. Each execution environment gets the amount of memory and processing power assigned to it by its definition, as well as 512 MB of ephemeral storage. It's important to note that these execution environments are completely independent of each other as they share absolutely no state.
For a more detailed description, check out the official page about the AWS Lambda execution environment.
Lambda Invocation
This is an invocation of one of our Lambda execution environments in response to a request. Although an execution environment can handle multiple invocations in a row, it only ever handles one invocation at a time. Hence our code does not need to be thread-safe (unless we explicitly make it multi-threaded). Since the execution environment is reused between invocations, state in the ephemeral storage is shared from one invocation to the next. That means, if we're not careful, we can run out of ephemeral storage. Similarly, in-memory state is also kept between consecutive invocations. This allows us to initialize components we can reuse for the lifetime of the execution environment. An invocation is instantaneously aborted if it exceeds its duration or memory limits, as defined by the Lambda function. It's a situation we should strive to avoid! Finally, it's important to note that the execution environment is suspended, along with any background threads, as soon as our code returns a response to the requests.
For more details, check out this fantastic write-up on understanding AWS Lambda scaling and throughput.
Lifecycle & Billing
The following graphic from the AWS Lambda execution environment documentation.
The billing of a Lambda invocation is based on the duration of the INVOKE phase only. The INIT phase is not billed unless provisioned concurrency is used, or the INIT phase exceeds 10s.
Check out this excellent write-up on the INIT phase billing for more details.
Additionally, the performance of the INIT phase is boosted for low memory configurations. Thus, unless the Lambda function is given a high memory limit (e.g. 5GB), the INIT phase takes the same amount of time for all configurations.
What's Next
The next post explores the compilation and deployment options that impact performance.
Top comments (0)