‹ All study guides

What Is AWS Lambda? Triggers, Concurrency and Cold Starts

Updated 27 October 2026 · 17 min read

AWS Lambda is a serverless compute service: you upload code, connect it to an event, and AWS runs it for you without you provisioning or managing a single server. You pay for the requests your function handles and for how long it runs, and AWS takes care of the capacity, the scaling and the patching underneath.

This is AWS Lambda explained from the first event to the exam room. It covers what happens inside Lambda when an event arrives, the parts around every function (the handler, runtimes, cold starts, triggers and event source mappings, the execution role, layers, concurrency, and versions and aliases), who uses it, the services it is normally paired with, and the limits worth memorising. It ends with the traps the Cloud Practitioner (CLF-C02), Solutions Architect Associate (SAA-C03) and DevOps Engineer Professional (DOP-C02) exams set around Lambda, each linked to a practice question. The same material is drawn on a whiteboard in the video linked at the end.

What is AWS Lambda?

Lambda lets you run code without thinking about the machine it runs on. You write a function, a small block of code that does one job. You connect it to a trigger, such as a file landing in Amazon S3, an HTTP request through Amazon API Gateway, or a message arriving in a queue. Lambda then runs the function only when that event happens, and stops when the work is finished. Each invocation runs on its own, with no shared state between them.

AWS handles everything below your code: server maintenance, capacity provisioning, automatic scaling and operating system patching. Your part is the application logic and its configuration. Under the hood, Lambda uses Firecracker virtualisation to give workloads VM-level isolation from one another.

A useful way to picture it is a car versus a taxi. Owning a server is like owning a car: you pay for it even while it sits in the car park, and the maintenance is your problem. Lambda is more like a taxi. You pay per ride, which in Lambda's case means per request plus the time your code runs, scaled by the memory you give it, and someone else keeps the cars running.

A naming note before going further. The Lambda documentation now calls the classic function type "Lambda Event Functions", next to newer compute types. The APIs, the CLI, CloudFormation and the exams all still say "Lambda function", and this guide does too.

How AWS Lambda works, step by step

Every invocation follows the same path, and knowing it makes most Lambda behaviour predictable:

  1. Something happens. A file is uploaded to S3, an API is called, a message arrives in a queue, a schedule fires, or someone calls the function directly from the SDK, CLI or console.
  2. Lambda receives the event as a JSON document and turns it into an object your code can work with.
  3. Lambda creates an execution environment for the function, or reuses a warm one that is already set up.
  4. The runtime calls your handler with two arguments: the event and a context object.
  5. The handler returns. A synchronous caller gets the result back; an asynchronous invocation discards the return value. The environment is then frozen and kept for a while in case another request arrives.

If more requests arrive while every environment is busy, Lambda creates more environments. That is how Lambda scales: out, not up, one environment per in-flight request.

The handler, event and context

The handler is the one method in your code that Lambda calls, and a function has only one. In Python the default handler is lambda_function.lambda_handler: the file name, then the function name. It takes two arguments:

  • event: the data to process. Its shape depends on the service that sent it, so an S3 notification looks nothing like an API Gateway request.
  • context: information about this invocation and the environment it runs in, such as the request ID (aws_request_id in Python).

Runtimes and deployment packages

Your handler runs on a runtime. Lambda manages runtimes for Java, Python, Node.js, .NET and Ruby, with current versions such as Node.js 24, Python 3.14, Java 25, .NET 10 and Ruby 4.0. Each major language version has its own identifier, such as nodejs24.x or python3.14, and you upgrade by changing it. Runtimes do retire: a function on a deprecated runtime keeps running but gets no more patches, and creating or updating functions on it is blocked later.

For Go, Rust or any other language, you use the OS-only runtime, provided.al2023 on Amazon Linux 2023, and bring a compiled binary or your own runtime interface client.

You ship the code in one of two package types, and you can't switch an existing function from one to the other:

  • .zip archive: up to 50 MB zipped when uploaded directly, larger through S3, and 250 MB unzipped including layers and custom runtimes.
  • Container image: up to 10 GB uncompressed, stored in Amazon ECR in the same Region as the function. It must be a Linux image built for one architecture.

Cold starts and the execution environment

An execution environment goes through three phases: Init, Invoke and Shutdown. Init does three things: it starts any extensions, bootstraps the runtime, and runs your static code, everything outside the handler. Init is limited to 10 seconds for on-demand functions.

The latency of downloading your code and running Init before the handler can start is the cold start. A request that lands on an environment already initialised is a warm start and skips it. The documentation says cold starts typically occur in under 1% of invocations, and can last from under 100 ms to over a second. You also pay for it: since August 2025, the Init phase is billed for on-demand .zip functions on managed runtimes.

The practical lesson is to put expensive setup outside the handler. Objects declared there, such as an SDK client or a database connection, stay initialised while the environment is reused, so only the cold start pays for them. Don't treat the environment as permanent, though. Lambda recycles environments every few hours even for busy functions, and resets one after a crash or timeout.

How events reach a function

Lambda has three invocation models, and the difference between them decides who retries a failure and where errors end up:

  • Synchronous: the caller waits for the function to finish and gets the response. API Gateway, Application Load Balancer and Amazon Cognito invoke this way.
  • Asynchronous: Lambda puts the event in an internal queue, replies straight away with HTTP 202, and a separate process feeds the event to your function. Amazon S3, Amazon SNS, EventBridge rules, CloudWatch Logs and CloudFormation invoke this way.
  • Event source mapping: Lambda itself polls a queue or stream and invokes your function with batches of records. SQS, Kinesis, DynamoDB Streams, Amazon MSK, self-managed Kafka, Amazon MQ and DocumentDB use this.

When you call the Invoke API yourself, the InvocationType picks the model: RequestResponse is synchronous and Event is asynchronous. There is also a function URL, a dedicated HTTPS endpoint for a function with AWS_IAM or NONE authentication, for when you need an endpoint without API Gateway.

Payload limits differ by model: 6 MB each for a synchronous request and response, and 1 MB for an asynchronous event.

Triggers vs event source mappings

This is one of the most common mix-ups. A trigger is configured in, and belongs to, the service that produces the event. S3 holds the notification configuration and pushes events to Lambda. An event source mapping is a Lambda resource: Lambda runs the pollers that read from SQS or a stream, and it pulls the records in.

The distinction matters when you troubleshoot. If S3 events are not arriving, you look at the bucket's notification configuration and the function's resource-based policy. If SQS messages are not being processed, you look at the mapping on the Lambda side. For background on the push and pull services themselves, the SQS vs SNS vs EventBridge guide compares them.

Either way, the same event can arrive more than once. Event source mappings are at-least-once, and asynchronous invocations can be retried, so AWS advises making function code idempotent: processing the same event twice should do no harm.

Permissions: execution role vs resource-based policy

A Lambda function has two kinds of permission, and they point in opposite directions.

  • Execution role (outward): what the function is allowed to do. It is an IAM role whose trust policy names lambda.amazonaws.com, and Lambda assumes it when the function runs. The managed policy AWSLambdaBasicExecutionRole grants just enough to write logs to CloudWatch Logs; a function that reads a DynamoDB table or writes to S3 needs those permissions added here.
  • Resource-based policy (inward): who is allowed to invoke or manage the function, such as S3, API Gateway, another AWS account or an organisation. When you add a trigger in the console, Lambda adds the needed statement to this policy for you.

So if a function fails with access denied while writing to a bucket, fix the execution role. If S3 can't invoke the function, fix the resource-based policy. The IAM users, roles and policies guide explains roles and resource-based policies across AWS more generally.

Lambda layers

A layer is a .zip archive of shared libraries, a custom runtime or configuration files that several functions can use. Lambda extracts it into /opt in the execution environment, so your code imports from it as if it were packaged with the function.

Layers have three rules worth remembering: a function can use up to five of them, they work only with .zip functions (a container image bakes its dependencies into the image instead), and they count toward the 250 MB unzipped limit, so they don't get you past it.

Concurrency and scaling

Concurrency is the number of requests your function is handling at the same moment. Because a standard execution environment handles one request at a time, it is roughly requests per second multiplied by the average duration: 100 requests per second at half a second each needs about 50 environments.

Three numbers shape how far and how fast a function scales:

  • Account quota: 1,000 concurrent executions per Region by default, shared by every function in the account, and raisable through Service Quotas. New accounts may start lower.
  • Scaling rate: each function can add 1,000 execution environments every 10 seconds.
  • Request-rate cap: ten times the concurrency quota, so 10,000 requests per second at the default.

When there is no concurrency left, extra requests are throttled with HTTP 429 (TooManyRequestsException). Throttles show up in the Throttles metric, not in Invocations or Errors.

Reserved vs provisioned concurrency

These two settings sound alike and do very different jobs:

  • Reserved concurrency: a slice of the account's concurrency set aside for one function. It is both a guarantee (other functions can't take it) and a cap (this function can't exceed it). It costs nothing extra. Setting it to 0 stops the function from processing anything, which is also the emergency brake for a function stuck invoking itself in a loop. You can reserve at most the unreserved concurrency minus 100, because 100 always stays for functions with no reservation.
  • Provisioned concurrency: a number of execution environments that Lambda initialises in advance, so requests routed to them start immediately with no cold start. It costs extra, it is set on a published version or an alias (never $LATEST), and Application Auto Scaling can adjust it on a schedule or by target tracking on its utilisation. Traffic beyond it spills over to on-demand environments, which can still cold-start.

The key point: reserved concurrency does nothing about cold starts. Only provisioned concurrency pre-initialises environments.

Versions and aliases

While you develop, you edit $LATEST, the unpublished version of the function. When you publish, Lambda creates a numbered version that is an immutable snapshot of the code and the configuration. Version numbers only go up and are never reused, even if you delete the function and recreate it.

An alias is a named pointer to a version, such as live or prod. Callers invoke the alias ARN, and you release by moving the alias to a new version, without changing anything on the caller's side.

A weighted alias splits traffic between two versions, for example 90% on version 5 and 10% on version 6. That is how canary deployments work on Lambda, and rolling back is a matter of putting the weight back. Both versions must be published, and they need the same execution role and dead-letter queue setup. AWS SAM with CodeDeploy automates the gradual shift, using deployment preferences such as Linear10PercentEvery2Minutes.

Who uses AWS Lambda

AWS's own case studies give a sense of the range:

  • Capital One adapted its tooling and release process to deploy tens of thousands of Lambda functions, and one of its applications cut costs by 90 percent after moving to Lambda.
  • FICO runs all its machine learning models on Lambda. When a loan application arrives, the event goes through API Gateway, which invokes a Lambda function that makes the decision.
  • Edmunds used Lambda functions, triggered through API Gateway and storing images in S3, to turn a library of 50 million vehicle images into 700 million new images in eight days, for a one-time cost of $6,000.

The common thread is work that arrives as events, in bursts, where paying for idle servers would be waste.

Services Lambda works with

Lambda rarely runs alone. A typical serverless application puts API Gateway in front, Lambda in the middle, DynamoDB for state and S3 for static content. The services you meet most often:

  • Amazon API Gateway: gives the function an HTTP endpoint, invokes it synchronously and relays the response to the client.
  • Amazon S3: invokes a function asynchronously when an object is created or deleted. A function that writes back into the bucket that triggers it can loop, so use a second bucket or a prefix filter.
  • Amazon DynamoDB: Lambda reads a table's stream through an event source mapping to do extra work each time the table changes.
  • Amazon SQS: Lambda polls the queue and invokes the function with a batch, ten messages by default; a successful run deletes them.
  • Amazon SNS and Amazon EventBridge: invoke functions asynchronously for fan-out and routing.
  • AWS Step Functions: runs functions as the steps of a workflow, which is the documented answer for long-running or stateful processes that one function shouldn't hold.
  • Amazon CloudWatch Logs: receives every invocation's logs in the log group /aws/lambda/<function-name>, provided the execution role allows it.
  • AWS IAM: supplies the execution role.

If you are weighing Lambda against servers you manage, the Amazon EC2 guide covers the other side of that choice.

Lambda limits and features to remember

Memory, CPU and timeout

Memory is configurable from 128 MB to 10,240 MB in 1 MB steps, and it is the main performance lever: CPU is allocated in proportion to memory, reaching the equivalent of one vCPU at 1,769 MB. Raising memory can shorten duration enough to cost the same or less.

The timeout defaults to just 3 seconds, which catches people out, and can be raised to a maximum of 900 seconds, or 15 minutes. Work that needs longer belongs in a workflow, such as Step Functions, rather than in one function.

Ephemeral storage and statelessness

Each environment gets a /tmp directory of 512 MB by default, configurable up to 10,240 MB. Its contents survive between warm invocations of the same environment, so it works as a cache, but nothing guarantees it will be there next time. Anything that must persist goes to S3, DynamoDB or a queue before the function exits. Environment variables are capped at 4 KB in total and are encrypted at rest; AWS recommends Secrets Manager for credentials.

Pricing

You pay for the number of requests and for duration, measured in GB-seconds (memory multiplied by run time). The free tier covers 1 million requests and 400,000 GB-seconds a month. Ephemeral storage up to 512 MB is included; provisioned concurrency is charged separately. Functions can run on x86_64, the default, or on arm64 (AWS Graviton2), which AWS prices lower per unit of duration; moving to arm64 needs arm64-compatible dependencies, layers and extensions. Check the Lambda pricing page for current rates in your Region.

Asynchronous retries, destinations and dead-letter queues

For asynchronous invocations, Lambda retries a failing function twice by default, waiting one minute and then two. You can set retries from 0 to 2 and a maximum event age of up to six hours, after which the event is discarded.

To keep failed events, you have two options:

  • Destinations: separate on-success and on-failure targets (SQS, SNS, Lambda or EventBridge, plus S3 for failures). The record holds both the request and the response, including the error.
  • Dead-letter queue: a standard SQS queue or SNS topic (not FIFO) that receives only the event content, with no response details.

For synchronous invocations, Lambda doesn't retry at all: the caller decides what to do.

SQS event source mappings

When SQS feeds a function, set the queue's visibility timeout to at least six times the function's timeout, so a throttled batch can be retried before the messages reappear. Turn on partial batch response (ReportBatchItemFailures) and return the IDs of only the failed messages, so the successful ones aren't processed again. And put the dead-letter queue on the SQS queue itself, as a redrive policy, not on the function.

Lambda in a VPC

By default a function can reach the internet. Attach it to a VPC and it can reach only that VPC's resources. Putting it in a public subnet does not give it internet access or a public IP; for that it needs private subnets routed through a NAT gateway. Lambda connects using Hyperplane network interfaces shared by functions with the same subnet and security group combination, and the execution role needs the AWSLambdaVPCAccessExecutionRole permissions to create them.

SnapStart

SnapStart cuts cold starts by taking a snapshot of the initialised environment when you publish a version, and resuming new environments from it. It supports Java 11 and later, Python 3.12 and later, and .NET 8 and later, but not Node.js, Ruby or OS-only runtimes. It works only on published versions and aliases, and can't be combined with provisioned concurrency.

AWS Lambda exam traps

Lambda turns up across the Cloud Practitioner, Solutions Architect Associate and DevOps Professional exams, at different depths. Cloud Practitioner asks you to recognise it as the serverless compute option; a practice question on running code when an image lands in S3 is the typical shape. The associate and professional exams test the components above, and these are the distinctions they come back to:

  • Reserved vs provisioned concurrency. A scenario describes slow first requests with an initialisation duration in the logs, and offers reserved concurrency as a tempting answer. It isn't: only provisioned concurrency removes cold starts. Work through the practice question on provisioned concurrency for a morning peak, the question at the end of the video, then a DevOps question on auto scaling provisioned concurrency where the spikes aren't predictable and target tracking replaces a schedule.
  • Concurrency vs database connections. Thousands of concurrent functions each opening a database connection is a connection problem, not a concurrency problem. Capping concurrency throttles your users; the fix in a practice question on Lambda and RDS connections is RDS Proxy.
  • The 15-minute limit and chained functions. When a process outgrows one function, or a chain of functions calling each other loses track of state, the answer is orchestration. See a practice question on Step Functions orchestration.
  • Destination vs dead-letter queue. If the requirement mentions the error response, or a different target per alias, it wants an on-failure destination; and FIFO queues are out. A practice question on async on-failure destinations sets exactly that trap.
  • Canary releases. A weighted alias splits traffic, but automatic rollback on errors comes from CodeDeploy with a CloudWatch alarm, as in a practice question on Lambda canary deployment and rollback.
  • Events vs polling. When something must react the moment a file arrives, an S3 event notification beats a scheduled function that lists the bucket; a practice question on S3 event notifications contrasts the two.
  • Role vs policy, trigger vs mapping, public subnet. "The function can't write to S3" is the execution role; "S3 can't invoke the function" is the resource-based policy; a dead-letter queue for an SQS source goes on the queue; a function in a public subnet still has no internet.

For more, work through the full question lists for Cloud Practitioner (CLF-C02), Solutions Architect Associate (SAA-C03) and DevOps Engineer Professional (DOP-C02), or start a timed test from the CLF-C02, SAA-C03 and DOP-C02 cert pages.

Frequently asked questions

What is AWS Lambda used for?

Running code in response to events without managing servers: APIs behind API Gateway, processing files uploaded to S3, consuming messages from SQS or streams from DynamoDB and Kinesis, scheduled jobs, and the steps of Step Functions workflows. It suits work that arrives in bursts and finishes in minutes.

How long can a Lambda function run?

Up to 900 seconds, or 15 minutes, per invocation. The default timeout is only 3 seconds, so raise it for anything that does real work. Longer processes should be split into steps and orchestrated, for example with Step Functions.

What is a Lambda cold start?

The delay while Lambda downloads your code, starts the runtime and runs your initialisation code in a new execution environment, before the handler can run. AWS says it typically affects under 1% of invocations. Provisioned concurrency or SnapStart reduce it; reserved concurrency doesn't.

What is the difference between reserved and provisioned concurrency?

Reserved concurrency guarantees and caps how many environments one function can use, and is free. Provisioned concurrency keeps a number of environments initialised in advance so they have no cold start, and costs extra.

How is AWS Lambda priced?

By the number of requests and by duration in GB-seconds, the memory you configure multiplied by how long the code runs. The monthly free tier includes 1 million requests and 400,000 GB-seconds. Provisioned concurrency and ephemeral storage above 512 MB are billed on top.

Is Lambda better than EC2?

Neither is better in general. Lambda removes server management and bills per request, which suits event-driven, bursty work that fits within 15 minutes. EC2 gives you a full server you control, for long-running processes, custom operating system needs or steady load.

Watch the whiteboard video

The video draws one Lambda function on a whiteboard and builds every component around it in order, so you can see an event travel through the execution environment, the three invocation lanes side by side and where each permission sits, and it works through the provisioned concurrency question at the end: AWS Lambda Explained: Triggers, Concurrency, Cold Starts and More on YouTube.

Practice questions