Note: This content was originally published at the Simple AWS newsletter. Understand the Why behind AWS Solutions. Subscribe for free! 3000 engineers and tech experts already have.
AWS Service: Lambda
tl;dr: Lambda is a serverless compute service that runs your code in response to events and automatically manages the underlying compute resources for you. It's the most basic serverless building block, especially for event-driven architectures.
Here's how it works:
You create a function and write the code that goes in it.
You set up a trigger for that function, such as an HTTP request
You configure CPU and memory, and give that function an execution role with IAM permissions
When the trigger event occurs, an isolated execution starts, receives the event, runs the code, and returns
You only pay for the time the code was actually running
Obviously, that code runs somewhere. The point is that you don't manage or care where ('cause it's serverless, you see). Every time a request comes in, Lambda will either use an available execution environment or start a new one. That means Lambda scales up and down automatically and nearly instantly.
Here's the fine details:
Supported languages are: Node.js, TypeScript, Python, Ruby, Java, Go, C# and PowerShell. Use a custom runtime for other languages.
Lambda functions can be invoked from HTTP requests, in response to events from other services, or at defined time intervals (cron jobs).
Billing is actually calculated as execution time * assigned memory (GB-seconds), plus a fixed charge per invocation. CPU is tied to memory.
Lambdas aren't actually instantaneous, there's a cold start (time to start the execution environment). Check the tips below for how to mitigate it.
Logs are automatically generated and sent to CloudWatch Logs.
Actionable tips
The most important tip is that you don't need to do everything in this list, and you don't need to do everything right now. But take your time to read it, I bet there's at least one thing in there that you should be doing but aren't.
Lambdas don't run in a VPC, unless you configure them for that. You need to do that if you want to access VPC resources, such as an RDS or Aurora database.
Use environment variables.
If you need secrets, put them in Secrets Manager and put the secret name in an environment variable.
As always, grant minimum permissions only.
Use versioning and aliases, so you can do canary deployments, blue-green deployments and rollbacks.
Use Lambda layers to reuse code and libraries.
For constant traffic, Lambda is more expensive than anything serverful (e.g. ECS). The benefit of Lambda is in scaling out extremely fast, and scaling in to 0 (i.e. if there's no traffic you don't pay).
Not everything needs to be serverless. Choose the best runtime for each service.
Use Lambda Power Tuning to optimize memory and concurrency settings for better performance and cost efficiency.
Set provisioned concurrency to guarantee a min number of hot execution environments. It's not free.
There's an account limit for concurrent Lambda executions. To ensure a particular function always has available limit, use reserved concurrency. It also serves as a maximum concurrency for that function.
Use compute savings plans to save money.
Already using containers? Run your containerized apps in Lambda. You could also consider ECS Fargate.
Don't use function URLs, if you want to trigger functions from HTTP(s) requests use API Gateway instead. Here's a tutorial, and we'll talk more about it next week.
If you have Lambdas that call other Lambdas, monitoring and tracing is a pain, unless you use AWS X-Ray.
Use SnapStart to improve cold starts by 10x (only in Java, for now...)
Code outside the handler only runs on environment initialization, not on every invocation. Put there everything you can, such as initializing the SDK.
Reduce request latency with global accelerators.
If you're processing data streams from Kinesis or DynamoDB, configure parallelization factor to process a shard with more than one simultaneous Lambda invocation.
Recommended tool(s)
Lambda is supported by every IaC tool out there. But if you're working with serverless, you'll want to check out these options (and pick one, don't mix them):
AWS SAM: It's like CloudFormation, but built for serverless. In fact, to deploy an app your SAM template is translated to CFN (or you can use Accelerate). And it lets you run Lambda functions locally.
Serverless Framework: Cloud-agnostic IaC tool specifically built for serverless. Works great with Lambda and many other serverless AWS services such as SQS, SNS, API Gateway, DynamoDB and more. The bad news is that, if a service is not supported, you can't work around that. Also lets you run your apps locally (though I've encountered a few problems with SNS and SQS).
AWS CDK: An IaC tool built for programmers. Most tools are declarative, you write a config file. CDK is imperative, you use a programming language and declare variables, control structures and loops. It's not specific for serverless, but it's a lot more dev-friendly than most. Also supports locally running your apps.
All of the above are great, but a bit limited for running things locally. LocalStack is better (though some features are paid). Try to use your IaC tool's capabilities, but if you hit a wall, definitely give LocalStack a shot.
Serverless Land is a place with a ton of serverless resources.
And check out the Serverlespressso AWS Workshop. They built a serverless app to serve coffee, and set up a coffee shop at the expo in AWS Re:Invent 2021 (I was there!).
Haiku(s)
Code without servers,
Scaling at the speed of light,
That's Lambda for you.
Understand the Why behind AWS Solutions.
Join over 3000 devs, tech leads, and experts learning how to architect cloud solutions, not pass exams, with the Simple AWS newsletter.
- Real-world scenarios
- The Why behind solutions
- How to apply best practices
If you'd like to know more about me, you can find me on LinkedIn or at www.guilleojeda.com
Top comments (5)
RE: the serverless framework
That's not strictly true since you can include cloudformation definitions as Resources?
I tried that a couple of times and didn't work for unsupported services. Maybe I did something wrong? I'll update the post!
I strongly suggest you take a look at sst.dev
Provides fantastic Typescript support, local debugging, higher level constructs like Static Site and NextJS and a tonne of other capabilities with first class DX
It also has a great, supportive community
As always I would recommend to take several of those advices with a grain of salt, many are only good advices under certain circumstances especially most after the 10th point:
use reserved concurrency -> be careful that it doesn't use up all the concurrency you have in your account which would prevent other lambdas from starting
use your container in Lambdas -> as a first step to migrate to Lambdas it's great, but there is a lot of downsides if you stop there, check my article on the subject
don't use Function URLS -> what is the argument to say that? Like many AWS features Function URLs have their use. They offer a simple and free alternative to API Gateway, but of course they don't offer much features compared to it. If you just want a way to trigger your Lambda they are perfect, they can even be secured with IAM.
put everything you can in the initializer -> it's good advice in most cases, but remember that you don't have control over the length of time it will be cached! That means if you put a DB connection in there and it times out, you need a mechanism to re-establish it (and there is other gotchas with code put in the initialization of lambdas)
reduce latency with global accelerators -> this is a very expensive service, I wouldn't recommend it except for very high load and world wide used apps
Why shouldn't we use function URLs? Thanks.