RUN CODE WITHOUT THINKING ABOUT SERVERS OR CLUSTERS
Virtual machines and containers made infrastructure management a lot easier. Lambda takes this another step further by virtualizing the runtime and only offering functions as a unit of scaling. As you're not responsible for any infrastructure, this is called serverless.
You'll only bring the code and the Lambda environment takes care of provisioning the underlying infrastructure and micro-containers to execute it.
The Evolution of Serverless
Don't get this wrong, serverless doesn't mean that there are no servers at all. It's just abstracted away and managed by AWS.
For a function invocation, AWS will spin-up a micro-container if there's none that's already available to run your function. The container is kept for a small period of time until the resources are freed so they can be assigned to other tasks.
Starting a micro-container on-demand takes time. This is called the cold start period. Lambda needs to download your code and start such a small container to run it. Additional time can be taken to bootstrap global logic of your function, e.g. loading your main framework.
There are a lot of best practices and tricks to reduce the time until your actual function code can execute:
Each provisioned Lambda micro-container is only able to process one request at a time. Even if there are multiple containers already provisioned, there can be another cold start if all of them are currently busy handling requests.
Looking at the invocation scenario above you can see that five Lambda micro-containers were started due to the request timings. The first re-use did only happen at request number six.
What's important here: everything outside the entrance method will be executed first when your function receives a cold start and won't disappear from memory until it's de-provisioned.
The execution of the global code outside of your handler method will be executed with high memory & CPU settings and isn't billed on the first hit.
Make use of this by always bootstrapping your core framework outside the handler method.
Reserved concurrency ensures that that is concurrency level is always available to your function.
This means:
Reduce your latency fluctuations by keeping the underlying infrastructure provisioned.
Keep in mind: this introduces additional costs. Also, deployments of your function will take more time as your updated code needs to be published to a fixed version.
Lambda's not only good for traditional workloads or REST backends. You can also use them with CloudFront. It enables you to execute code at different stages when your CloudFront distribution is called.
By that you can for example easily implement authorization rules or route calls to different edge locations.
Generally, you can do a lot as you're also able to use the AWS SDK and invoke other services.
Another use: CloudFront functions - the lightweight, cheaper alternative with a reduced feature set.
Necessary dependencies need to be included in your deployment package. As dependencies can quickly reach multiple megabytes, packaging and code deployment can take up more time, even if you just want to update your own code.
With Lambda Layers, you can bundle your dependencies separately and then attach them to one or several functions. You can also use multiple layers in the same function.
Be aware, that your Lambda deployment unit and all of the attached layers can't exceed 250 MB in an unzipped state.
Your function is protected on AWS. By default, there's no ingress traffic possible to your function, but all egress to the internet. You can attach your function to a VPC to access other private resources or restrict egress traffic to the internet via security groups and network access control lists.
We believe that cloud-native development has serverless computing are the future as they come with great benefits:
You can publish immutable versions for your Lambda functions and then use a reference at all places that need to call these functions.
This allows you to easily switch between different function versions. If your function is exposed to the internet via AWS API Gateway, you can also integrate canary deployments by using weighted aliases. This enables you to send only a fraction of traffic to your new version to check functional spikes while the major load resides on your stable version.
If your Lambda function is invoked for tasks to complete successfully, you can use the Lambda destination feature to send the results of the function execution to a different destination, like a SQS queue. This can be useful for debugging or for handling error cases.
Having in-depth insights into your Lambda-powered, event-driven architecture is still a goliath task. Mostly, you'll design event-driven architectures that involve a lot of other services like for example SQS, so there's just not a single log group to monitor.
CloudWatch helps a lot in the first place via Metrics & Alerts. Many of them are predefined, like:
Familiarize yourself with CloudWatch's possibilities.
For enterprise-scale applications rely on third-party tools like dashbird.io to get an overview of your Lambdas and other related common services like API Gateway, SQS, SNS, DynamoDB & many more in a single place.
Lambda is continuously improved since Lambda's release date back in 2014. AWS introduced among other things: