Cloud / AWS Lambda Interview questions
Last updated
1. What is AWS Lambda?
AWS Lambda is a serverless, event-driven compute service that runs your code in response to triggers without you having to provision or manage servers.
You upload a function's code, Lambda handles the underlying compute, patching, and capacity, and it runs your code only when a matching event occurs, such as an API call, a file upload to S3, or a new message on a queue.
Billing is based on the number of requests and the compute time consumed, measured in GB-seconds, so you pay only while your code is actually executing.
Because there is no idle server to maintain, Lambda is widely used for APIs, data processing pipelines, automation scripts, and glue logic between AWS services.
Take quiz
Number of EC2 instances reserved
Requests and compute time (GB-seconds)
Total storage allocated to the function
Number of IAM roles attached
The underlying server OS and patching
Your function code and its configuration
The physical data center hardware
The hypervisor running your function
2. What is a Lambda function?
A Lambda function is the deployable unit of code that AWS Lambda executes - it packages your handler code, any dependencies, and a set of configuration settings (memory, timeout, runtime, IAM role) into one resource.
Each function is identified by a name and ARN, and it exposes a single handler method that Lambda calls with the incoming event whenever the function is invoked.
Functions can be packaged as a .zip archive uploaded directly, or as a container image pushed to Amazon ECR, which is useful when dependencies are large or you already have a Docker-based build pipeline.
Configuration (memory, environment variables, VPC settings) is versioned separately from code, letting you update either independently.
Take quiz
Only the raw source code with no config
Handler code plus configuration like memory and IAM role
A permanently running virtual machine
A static website hosted on S3
A container image stored in Amazon ECR
A CloudFormation stack export
An EBS snapshot
A Route 53 hosted zone
3. What is the purpose of a Lambda execution role?
The execution role is an IAM role that Lambda assumes on your function's behalf while it runs, and it determines which AWS services and resources the function is allowed to call.
For example, a function that reads from DynamoDB and writes to S3 needs an execution role with policies granting dynamodb:GetItem and s3:PutObject permissions; without them, those calls fail with an AccessDenied error at runtime, not at deployment time.
This role is separate from the resource-based policy attached to the function itself, which controls who is allowed to *invoke* the function (for example, allowing API Gateway or S3 to trigger it).
Best practice is to scope the execution role to the minimum permissions the function actually needs rather than reusing a broad, shared role.
Take quiz
Which users can view the function's source code
What AWS resources the function's code can access at runtime
How long the function can run
Which region the function is deployed in
The execution role's trust policy
A resource-based (permissions) policy on the function
The account's billing policy
The VPC's network ACL
4. What are the supported runtimes in AWS Lambda?
Lambda provides managed runtimes for several popular languages, each maintained by AWS with periodic security patches: Node.js, Python, Java, .NET (C#/PowerShell), Ruby, and Amazon's own Amazon Linux-based provided.al2023 runtime.
Languages without a first-party managed runtime - such as Go, Rust, or Kotlin - can run through a custom runtime built on provided.al2/provided.al2023, which implements the Lambda Runtime API yourself or via a community bootstrap.
Every runtime is also available through container images, letting you bring any base image (including ones with OS-level dependencies) as long as it implements the Lambda Runtime Interface Client.
| Managed Runtime | Latest Family Example |
| Node.js | Node.js 20.x / 22.x |
| Python | Python 3.12 / 3.13 |
| Java | Java 17 / 21 |
| .NET | .NET 8 |
Take quiz
A custom runtime on provided.al2023
Only by rewriting it in Python
Lambda@Edge exclusively
AWS Batch instead of Lambda
Never need any dependencies
Have large or OS-specific dependencies
Only run for under 1 second
Cannot use IAM roles
5. What is a Lambda handler function?
The handler is the specific method in your code that Lambda invokes to start execution - it's the entry point you configure as filename.method_name (or the equivalent for your runtime).
Lambda calls it with two main arguments: the event, a JSON-like object describing what triggered the invocation, and the context, which carries runtime information such as the remaining execution time.
def lambda_handler(event, context): name = event.get("name", "world") return {"statusCode": 200, "body": f"Hello, {name}"}
Whatever the handler returns becomes the function's output for a synchronous invocation, and any unhandled exception it raises is recorded as a function error in CloudWatch.
Take quiz
request and response
event and context
input and output
session and payload
Whatever value the handler function returns
The last line printed to stdout
The function's memory setting
The execution role's ARN
6. What are Lambda layers?
A layer is a .zip archive containing libraries, custom runtimes, or other dependencies that can be attached to one or more functions, so shared code doesn't have to be bundled into every deployment package.
Lambda extracts each attached layer into the /opt directory of the execution environment in the order they're listed, and a function can use up to five layers at once.
Layers are commonly used to ship a Python virtual environment, a set of Node.js modules, monitoring agents, or the AWS Lambda Powertools utility library, keeping the function's own deployment package small and focused on business logic.
Each layer is versioned independently, so you can update a shared dependency without touching every function that consumes it - you just point the function at the new layer version.
Take quiz
/tmp
/opt
/var/task
/home
Up to 2
Up to 5
Up to 20
Unlimited
7. How do you deploy a Lambda function?
The simplest path is uploading a .zip package or pointing to a container image in ECR through the Lambda console or the aws lambda create-function/update-function-code CLI commands.
For repeatable, production deployments, most teams use Infrastructure-as-Code: AWS SAM or the Serverless Framework for Lambda-focused apps, or the AWS CDK/CloudFormation when Lambda is one part of a larger stack.
- Package code and dependencies (zip or container image).
- Push the artifact (S3 for zips, ECR for images).
- Create or update the function resource with the new code reference.
- Publish a version and optionally shift an alias to it.
CI/CD pipelines (CodePipeline, GitHub Actions, Jenkins) typically automate these steps, running tests before promoting a new version to a "prod" alias.
Take quiz
Amazon S3 only
Amazon ECR
AWS Secrets Manager
Amazon CloudFront
AWS SAM
Amazon Route 53
AWS Config
Amazon Cognito
8. What is the purpose of the Lambda deployment package?
The deployment package is the artifact that contains your function's compiled or interpreted code plus any third-party libraries it needs, and it's what Lambda actually deploys and runs.
For a .zip package uploaded directly through the API or console, the limit is 50 MB compressed and 250 MB uncompressed (including layers); uploading via S3 instead of directly raises the compressed limit to 250 MB as well.
Container images support up to 10 GB, which is why teams with heavy dependencies (ML libraries, native binaries) often switch to the container image packaging model.
Keeping the package lean matters beyond just staying under the limit - a smaller package downloads and initializes faster, which directly reduces cold-start latency.
Take quiz
10 MB
50 MB
250 MB
1 GB
50 MB
250 MB
1 GB
10 GB
9. What are Lambda environment variables?
Environment variables are key-value pairs you attach to a function's configuration and read at runtime through the standard environment-variable APIs of your language, such as process.env.MY_VAR in Node.js or os.environ["MY_VAR"] in Python.
They're the standard way to pass configuration - database endpoints, feature flags, log levels - without hardcoding values into the code, so the same package can run in dev, staging, and prod with different settings.
By default they're encrypted at rest using an AWS-managed KMS key; you can instead supply your own customer-managed key for stricter control, and Lambda also supports encrypting specific values in transit via helper SDK calls.
They are not meant for large payloads - the combined size of all environment variables for a function is capped at 4 KB.
Take quiz
4 KB
40 KB
4 MB
No limit
Stored in plain text with no protection
Encrypted using an AWS-managed KMS key
Only available to Lambda@Edge
Deleted after each invocation
10. Define cold start in AWS Lambda?
A cold start is the extra latency incurred the first time (or after a period of inactivity) a request hits a function and Lambda must create a brand-new execution environment before it can run your code.
That setup includes downloading the deployment package, starting the runtime, and running any code outside the handler (SDK client creation, static initializers) - only after that does the actual handler invocation begin.
Subsequent requests that reuse the same warm environment skip all of that and go straight to the handler, which is why cold starts are occasional rather than constant under steady traffic.
Cold start duration is influenced by package size, runtime choice (compiled languages like Java/.NET are typically slower to initialize than Node.js/Python), memory allocation, and whether the function is attached to a VPC.
Take quiz
Every single invocation of any function
Lambda must create a new execution environment before running the handler
The function's memory is set below 128 MB
A function is invoked from Lambda@Edge only
A smaller deployment package
Using provisioned concurrency
A larger deployment package with heavy dependencies
Running with 10,240 MB of memory instead of 128 MB
11. What is the maximum execution timeout for a Lambda function?
A Lambda function can run for a maximum of 15 minutes (900 seconds) per invocation; the default timeout when you first create a function is only 3 seconds, which is far too short for most real workloads and is usually the first setting people raise.
If your code hasn't returned by the configured timeout, Lambda forcibly terminates the execution environment and reports a Task timed out error in CloudWatch Logs, and any async invocation retry logic kicks in as if the function had failed.
Timeout is set per function (or per version) alongside memory, and it should be set with headroom above the function's typical (p99) duration rather than tuned to the exact average, since downstream dependencies (databases, APIs) can spike unpredictably.
Workloads genuinely needing longer than 15 minutes should be redesigned as a Step Functions state machine or moved to a different compute service such as AWS Batch or ECS.
Take quiz
3 seconds
5 minutes
15 minutes
1 hour
3 seconds
30 seconds
1 minute
15 minutes
12. Describe the event source mapping in Lambda?
An event source mapping is a Lambda resource that continuously polls a stream or queue on your behalf - for sources like Amazon SQS, Kinesis Data Streams, DynamoDB Streams, and Amazon MQ - and invokes your function synchronously with a batch of records once enough arrive or a batching window elapses.
This differs from push-based triggers (like S3 or API Gateway), where the source itself calls Lambda directly; here, the Lambda service manages the polling loop, checkpointing, and scaling of pollers internally.
Key tunables include batch size, maximum batching window, and for streams, parallelization factor (multiple batches per shard) and starting position (TRIM_HORIZON/LATEST).
Because polling failures block a given shard or partition until resolved (for streams), configuring retry limits, bisecting batches on error, and destinations for failed records are important parts of designing a resilient mapping.
Take quiz
Directly rendering a web UI
Polling sources like SQS or Kinesis and invoking the function with batches
Storing function code in S3
Encrypting environment variables
Timeout
Batch size
Memory allocation
Execution role
13. What are the types of Lambda invocation models?
Lambda supports three invocation models, and understanding which one a given trigger uses is essential for reasoning about retries and error handling.
| Model | Behavior | Example Triggers |
| Synchronous | Caller waits for the response; errors are returned immediately to the caller. | API Gateway, ALB, direct SDK Invoke |
| Asynchronous | Event is queued internally; Lambda retries on failure and can route to a DLQ/destination. | S3, SNS, EventBridge |
| Poll-based (event source mapping) | Lambda service polls the source and invokes synchronously with a batch. | SQS, Kinesis, DynamoDB Streams |
Choosing the right mental model matters: a synchronous caller (like API Gateway) needs your function to return quickly and propagate meaningful status codes, while asynchronous and poll-based sources rely on Lambda's own retry and failure-handling configuration instead.
Take quiz
Synchronous
Asynchronous
Poll-based
Scheduled
Poll-based event source mapping
Synchronous, blocking S3 until Lambda finishes
Asynchronous invocation
Lambda@Edge only
14. List the triggers that can invoke a Lambda function?
Lambda can be triggered by dozens of AWS services and direct calls; the most commonly used ones fall into a few categories.
- API/web: Amazon API Gateway, Application Load Balancer, Lambda function URLs.
- Storage/data events: Amazon S3 (object created/removed), DynamoDB Streams.
- Messaging: Amazon SQS, Amazon SNS, Amazon MQ.
- Streaming: Amazon Kinesis Data Streams, Amazon MSK (Kafka).
- Scheduling/events: Amazon EventBridge (rules, schedules), CloudWatch Alarms.
- Content delivery: Amazon CloudFront via Lambda@Edge.
- Auth/identity: Amazon Cognito triggers (pre sign-up, post confirmation, etc.).
- Orchestration/direct: AWS Step Functions, and direct
Invokecalls via SDK or CLI.
Each trigger shapes the event object differently, so handler code typically starts by parsing the specific structure that source sends (for example, Records[].s3.object.key for S3, versus Records[].Sns.Message for SNS).
Take quiz
DynamoDB Streams
Amazon Route 53
AWS Budgets
Amazon WorkSpaces
Lambda@Edge via CloudFront
EventBridge Scheduler
Cognito pre-token-generation
AWS Config rules
15. What is the purpose of the AWS Lambda context object?
The context object, passed as the second argument to the handler, exposes runtime and invocation metadata that isn't part of the business event itself.
| Property/Method | What it gives you |
getRemainingTimeInMillis() |
Milliseconds left before the configured timeout fires. |
functionName / functionVersion |
Which function and version is currently executing. |
memoryLimitInMB |
The configured memory size for this invocation. |
awsRequestId |
Unique ID for correlating this invocation across logs. |
logGroupName / logStreamName |
Where this invocation's logs are written in CloudWatch. |
A common real-world use is calling getRemainingTimeInMillis() before a slow downstream call so the function can fail gracefully or return partial results instead of hitting a hard timeout.
Take quiz
memoryLimitInMB
getRemainingTimeInMillis()
functionVersion
logStreamName
The first argument, replacing the event
The second argument, alongside the event
A global variable only, never an argument
Part of the response body
16. How do you set memory allocation for a Lambda function?
Memory is set in the function's configuration - via console, CLI (aws lambda update-function-configuration --memory-size), or IaC templates - as a value between 128 MB and 10,240 MB, adjustable in 1 MB increments.
What makes this setting distinctive is that Lambda allocates CPU power proportionally to memory: a function configured with more memory also gets a larger share of vCPU, which is why CPU-bound functions often finish faster (and sometimes cheaper overall) at a higher memory setting despite the higher per-millisecond price.
At around 1,769 MB a function effectively gets the equivalent of one full vCPU, and functions can be granted multiple vCPUs at higher memory tiers.
Because the right value depends on the workload, teams often use tools like AWS Lambda Power Tuning to benchmark cost versus duration across memory settings rather than guessing.
Take quiz
Only the storage in /tmp
Its proportional share of CPU power
The maximum timeout allowed
The number of layers it can use
64 MB to 1024 MB
128 MB to 10,240 MB
256 MB to 3,008 MB only
1 GB to 100 GB
17. What is Lambda@Edge?
Lambda@Edge lets you run Lambda functions at Amazon CloudFront edge locations around the world, close to end users, rather than in a single AWS region.
You can hook into four points in a CloudFront request lifecycle: viewer request, origin request, origin response, and viewer response - for example, rewriting a viewer request's URL, or adding security headers to an origin response before it's cached.
It has tighter constraints than regional Lambda: only the Node.js and Python runtimes are supported, functions must be authored in the us-east-1 region before CloudFront replicates them, environment variables and layers aren't supported, and execution time/memory limits are smaller for viewer-triggered events than for origin-triggered ones.
Typical uses include A/B testing at the edge, header-based redirects, image resizing hints, and lightweight authentication/authorization checks before a request reaches the origin.
Take quiz
eu-west-1
us-east-1
ap-south-1
Whichever region the origin is in
Viewer request
Origin response
Database write
Origin request
18. What is the purpose of a dead-letter queue in Lambda?
A dead-letter queue (DLQ) is an optional SQS queue or SNS topic that captures the event payload from an asynchronous invocation after Lambda has exhausted its automatic retries and still failed to process it.
Without a DLQ configured, an event that keeps failing async processing is simply discarded once retries and the maximum event age are exceeded, which means silent data loss unless you're watching CloudWatch metrics closely.
Routing failed events to a DLQ lets you inspect, replay, or alert on them instead of losing them - a common pattern is a CloudWatch alarm on the DLQ's message count.
DLQs are considered the older mechanism; AWS now recommends on-failure destinations (SQS, SNS, another Lambda function, or EventBridge) for async invocations, since destinations also capture invocation metadata like the error and can also record on-success outcomes, not just failures.
Take quiz
The function succeeds on the first try
Lambda has exhausted retries and processing still failed
The function times out at exactly 15 minutes only
The event source mapping is disabled
No configuration options at all
Richer invocation metadata and support for success outcomes too
Guaranteed real-time delivery under 1ms
Automatic code deployment on failure
19. Why do we use provisioned concurrency in Lambda?
Provisioned concurrency keeps a specified number of execution environments pre-initialized and warm, so incoming requests skip the cold-start init phase entirely and go straight to handler execution with consistently low latency.
It's used for latency-sensitive workloads - synchronous APIs, user-facing endpoints, or functions with heavy initialization (large SDK clients, ML model loading) - where even an occasional multi-hundred-millisecond cold start would violate an SLA.
Unlike normal on-demand Lambda, provisioned concurrency is billed for the time it's configured, whether or not it's actively invoked, in addition to standard per-invocation duration charges, so it trades cost predictability for latency guarantees.
It's commonly paired with Application Auto Scaling to raise or lower the provisioned amount on a schedule or based on utilization, matching known traffic patterns like a morning spike.
Take quiz
Lower per-GB-second pricing
Eliminating cold starts by keeping environments pre-warmed
Unlimited execution timeout
Automatic multi-region replication
Only when the function is actually invoked
For the configured duration, whether invoked or not, plus normal invocation charges
Only during the first 24 hours after configuration
Never - it is a free feature
20. How does Lambda handle concurrency limits?
Every AWS account has a regional concurrent execution limit (a soft limit, commonly starting at 1,000, raisable via support request) shared across all functions in that account and region.
Within that pool, you can set reserved concurrency on a specific function to guarantee it a slice of that pool and, simultaneously, cap how high it can scale - protecting downstream systems like a relational database from being overwhelmed.
Any function without reserved concurrency draws from the shared unreserved pool; if the account limit is reached, further invocation attempts are throttled and return a TooManyRequestsException (HTTP 429) to synchronous callers, or are retried automatically for async/poll-based sources.
Monitoring the ConcurrentExecutions and Throttles CloudWatch metrics is the standard way to catch this before it affects users.
Take quiz
It queues indefinitely with no error
It is throttled and returns a 429 TooManyRequestsException
It automatically increases memory to compensate
It is routed to a different AWS account
Guarantees and caps that function's slice of the concurrency pool
Increases the account-wide limit automatically
Disables all retries for that function
Applies only to Lambda@Edge functions
21. What is the difference between concurrency and parallelism in Lambda?
Concurrency in Lambda refers to the number of execution environments actively processing invocations at the same instant - it's the scaling dial the service uses to handle load. Parallelism refers to work genuinely happening at the same time, which within a single environment depends on your code (multi-threading) rather than Lambda's scaling behavior.
| Aspect | Concurrency | Parallelism |
| Controlled by | Lambda's scaling + reserved/provisioned settings | Your code's threading/async logic inside one environment |
| Unit | Number of execution environments | Number of tasks truly running simultaneously on available vCPUs |
| Scaling method | Horizontal - more environments | Vertical - more vCPU/threads within one environment |
In practice, Lambda achieves high throughput mainly through concurrency (many parallel environments each handling one invocation), while parallelism inside a single invocation is limited by the vCPUs granted at your configured memory level.
Take quiz
Concurrency - spinning up more execution environments
The account's IAM permissions
The function's timeout setting
The number of layers attached
The region the function is deployed in
The code's own threading/async design and available vCPUs
The event source mapping's batch size only
The function's ARN
22. How does Lambda scale to handle multiple requests?
Lambda scales horizontally and automatically: for each concurrent request beyond what existing warm environments can absorb, it spins up a new, isolated execution environment running your code, up to the account/function's concurrency limits.
Scaling isn't unlimited-instantly - accounts get an initial burst capacity (historically 500-3,000 concurrent executions depending on region) available immediately, after which concurrency increases at a steady rate (roughly 500 additional executions per minute) until it hits the account's overall limit.
For poll-based sources like Kinesis or DynamoDB Streams, scaling is additionally bound by the number of shards, since Lambda processes each shard with one poller at a time (unless parallelization factor is increased).
This model means a sudden traffic spike can briefly cause throttling on very bursty workloads even before the account-level cap is reached, which is why reserved/provisioned concurrency and client-side backoff matter for spiky traffic.
Take quiz
Increasing memory of a single environment indefinitely
Creating additional isolated execution environments in parallel
Merging requests into fewer environments
Switching runtimes automatically
The number of shards in the stream
The function's memory setting
The number of layers attached
The AWS account's billing plan
23. When should you use synchronous vs asynchronous invocation?
Use synchronous invocation when the caller needs the function's result immediately to continue its own logic - the classic case is API Gateway or an ALB calling Lambda to build an HTTP response, where the client is waiting on the line.
Use asynchronous invocation when the caller just needs to hand off an event and move on - S3 notifying Lambda of a new upload, or SNS fanning out to multiple functions, where nothing is blocked waiting on the function's result.
| Aspect | Synchronous | Asynchronous |
| Errors | Returned directly to the caller | Retried by Lambda (default 2 retries), then DLQ/destination |
| Typical sources | API Gateway, ALB, direct Invoke | S3, SNS, EventBridge |
| Caller behavior | Blocks until response or timeout | Returns immediately after event is accepted |
Choosing wrong shows up quickly: forcing a long-running batch job to run synchronously behind an API Gateway request risks hitting API Gateway's own 29-second integration timeout.
Take quiz
Asynchronous invocation
Synchronous invocation
Poll-based invocation only
No invocation model applies to APIs
Immediately deletes the function
Retries it automatically before giving up
Silently ignores the failure with no retry
Converts it to a synchronous call
24. What is the difference between Lambda and EC2 for compute?
Lambda and EC2 sit at different points on the control-versus-convenience spectrum for running code.
| Aspect | AWS Lambda | Amazon EC2 |
| Server management | None - fully managed | You manage the OS, patching, scaling |
| Billing | Per request + duration (ms-level) | Per instance-hour/second while running, even if idle |
| Scaling | Automatic, near-instant, per request | Manual or via Auto Scaling groups, slower to react |
| Max runtime | 15 minutes per invocation | Unbounded - can run continuously |
| Best fit | Event-driven, bursty, short-lived tasks | Long-running processes, custom OS/software needs, steady high load |
A practical rule of thumb: choose Lambda when workloads are event-driven and short, and EC2 (or containers on ECS/EKS) when you need long-running processes, specialized OS-level control, or workloads where sustained high utilization makes always-on instance pricing cheaper than per-invocation billing.
Take quiz
You are billed while the instance is idle and running
It has no maximum execution duration per invocation
Both A and B
It automatically scales per individual request with zero configuration
Always-on, steady, long-running background daemons
Short, event-driven, bursty workloads
Workloads needing a custom Linux kernel
Applications requiring root-level OS access
25. How do you use VPC with a Lambda function?
You attach a Lambda function to a VPC by specifying one or more subnets and at least one security group in its network configuration - this is required whenever the function needs to reach resources that aren't publicly reachable, like an RDS instance or an internal ElastiCache cluster.
Once attached, Lambda creates elastic network interfaces (ENIs) in the specified subnets so the execution environment can route traffic into that VPC's private network.
A common mistake is forgetting that a VPC-attached function still needs a path to the public internet for calls to non-VPC AWS services (like most S3/DynamoDB endpoints) or third-party APIs - that requires routing through a NAT gateway in a private subnet, or using a VPC endpoint for AWS-service-only traffic.
VpcConfig: SubnetIds: - subnet-0abc123 - subnet-0def456 SecurityGroupIds: - sg-0123456789
Take quiz
Public S3 endpoints only
Private resources like an RDS instance inside that VPC
The Lambda console itself
CloudWatch Logs exclusively
A NAT gateway in a private subnet (or equivalent routing)
A dead-letter queue
A Lambda layer
An IAM execution role alone
26. Why does a Lambda function in a VPC take longer to start?
Historically, attaching Lambda to a VPC added significant cold-start latency because Lambda had to create a dedicated elastic network interface (ENI) for each unique subnet/security-group combination on demand, and ENI creation could take several seconds.
AWS re-architected this with the Hyperplane-based networking model (rolled out around 2019), which pre-creates and shares ENIs across functions and execution environments in the same account/VPC/subnet combination, largely eliminating the old per-invocation ENI delay.
Some residual latency can still appear on the very first cold start for a brand-new subnet/security-group pairing in an account, since the shared ENI pool for that combination has to be established once - after that, subsequent functions reusing the same networking configuration benefit from the existing pool.
In practice, VPC attachment today adds only a small, mostly one-time cost rather than the multi-second penalty seen before the Hyperplane change.
Take quiz
Removing the need for security groups entirely
Pre-creating and sharing ENIs across functions in the same VPC/subnet
Increasing the maximum timeout to 1 hour
Disabling VPC support altogether
On-demand ENI creation per unique network configuration
Excessive IAM permission checks
Lack of available memory tiers
DNS caching in CloudFront
27. How is Lambda function versioning managed?
Every function starts with a mutable pointer called $LATEST, which always reflects the most recently deployed code and configuration.
Calling Publish Version takes an immutable snapshot of $LATEST at that moment - code, configuration, and layers - and assigns it a sequential number (1, 2, 3…). Once published, a version's code can never be changed; you can only create a new version for further changes.
Each version has its own unique ARN, so downstream systems can pin to an exact, unchanging version if they need reproducibility, while $LATEST keeps evolving as you keep deploying.
Versioning by itself is rarely used directly by callers in production - it's the foundation that aliases build on to support traffic shifting and safer rollouts.
Take quiz
$LATEST
A published version like "3"
The execution role
An event source mapping
Can still be edited in place
Becomes immutable and cannot be changed
Is automatically deleted after 30 days
Is merged back into $LATEST
28. What is the difference between Lambda aliases and versions?
A version is an immutable, numbered snapshot of a function's code and configuration; an alias is a named, mutable pointer that references one (or, with weighting, two) versions.
| Aspect | Version | Alias |
| Mutability | Immutable once published | Mutable - can be repointed anytime |
| Naming | Sequential numbers (1, 2, 3…) | Custom names like "prod" or "staging" |
| Traffic shifting | Not supported directly | Supports weighted splits across two versions |
| Typical use | Historical, reproducible snapshot | What clients/triggers actually target |
In practice, teams point their API Gateway integration or event trigger at an alias like prod, then shift that alias between versions for canary or blue/green style releases - clients never need to know the underlying version number changed.
Take quiz
An alias with weighted routing
The execution role
A Lambda layer
The $LATEST pointer alone
An alias
A published version
An environment variable at runtime
The account's concurrency limit
29. How do you troubleshoot a Lambda timeout error?
Start with the REPORT line that CloudWatch Logs writes for every invocation - it shows actual Duration versus the configured timeout, plus Billed Duration and Max Memory Used, which quickly tells you whether the function is close to the limit or wildly exceeding it.
- Check whether the timeout is a one-off spike or consistent, using CloudWatch's
Durationmetric over time. - Look for slow downstream calls - a database query, a third-party API, or a cold connection inside a VPC - using AWS X-Ray tracing to see a breakdown of time spent per segment.
- Rule out cold-start-inflated duration versus genuine handler slowness by comparing
Init Durationagainst handler execution time in the logs. - Check for retry loops: if a downstream call itself retries internally with long backoff, it can silently eat the whole timeout budget.
Once the bottleneck is identified, the fix is usually one of: raising the timeout (with headroom), increasing memory (more CPU can speed up CPU-bound work), fixing the slow dependency, or redesigning the flow (e.g., moving heavy work to Step Functions or SQS).
Take quiz
The function's IAM policy JSON
Actual duration, billed duration, and max memory used
The VPC's route table
The account's monthly bill
AWS X-Ray
Amazon Route 53
AWS Config
Amazon Cognito
30. When would you choose Step Functions over chaining Lambdas directly?
Choose Step Functions when a workflow has multiple steps with branching logic, needs built-in retry/error-handling per step, must pause and wait (for a human approval or an external callback), or needs to run longer than Lambda's 15-minute cap by orchestrating multiple invocations over time.
Having one Lambda function directly invoke another to "chain" logic is a known anti-pattern: it hides the workflow's shape in code instead of a visual, auditable state machine, doubles the compute you pay for (the caller function sits billed and idle while waiting on the callee), and risks runaway recursive costs if a bug causes repeated self-invocation.
Step Functions instead models each Lambda call as a discrete state in a state machine, giving you a visual execution history, native retry/catch policies per state, parallel and choice branches, and integration with dozens of AWS services without extra glue code.
Simple, single-purpose functions triggered independently by events (no orchestration needed) don't need Step Functions at all - it earns its complexity only once multi-step coordination is genuinely required.
Take quiz
Improved cost efficiency
Doubled billed compute time and potential runaway recursive invocations
Automatic visual workflow diagrams
Guaranteed sub-second latency
A single, unconditional function call with no branching
Multi-step orchestration with retries, branching, and wait states
Nothing but a cron-style schedule
To run only inside Lambda@Edge
31. What is the difference between reserved concurrency and provisioned concurrency?
These two settings sound similar but solve different problems and are often used together.
| Aspect | Reserved Concurrency | Provisioned Concurrency |
| Purpose | Guarantee and cap a function's slice of the account's concurrency pool | Keep environments pre-warmed to remove cold starts |
| Cold starts | Not addressed - still occur normally | Eliminated for the provisioned amount |
| Cost impact | No extra charge by itself | Billed for the reserved time regardless of invocations |
| Effect on other functions | Reduces the shared pool available to others | No effect on the account-wide pool |
A latency-critical function often sets both: reserved concurrency to guarantee capacity isn't stolen by other functions, and provisioned concurrency (at or below that reserved amount) to guarantee those available environments are already warm.
Take quiz
Reserved concurrency
Provisioned concurrency
Dead-letter queue configuration
Environment variable encryption
How warm the execution environment is
How much of the account's concurrency pool the function can use, and reserves it from others
The function's runtime language
The maximum deployment package size
32. How does Lambda retry failed asynchronous invocations?
For asynchronous invocations, Lambda automatically retries a failed execution up to two additional times by default (three attempts total), with a short delay between attempts that increases as retries progress.
You can tune this via MaximumRetryAttempts (0, 1, or 2) and MaximumEventAgeInSeconds (from 60 seconds up to 6 hours) - once either limit is hit, the event is either dropped, sent to a configured dead-letter queue, or routed to an on-failure destination if one is set.
Because retries redeliver the same event, handlers invoked asynchronously should be written to be safe against being run more than once for the same input - this is the same idempotency concern that applies to poll-based sources.
Note this retry behavior is specific to asynchronous invocation; synchronous callers and poll-based event source mappings have their own, different retry semantics.
Take quiz
Zero
Up to 2 additional attempts
Unlimited retries
Exactly 10
MaximumEventAgeInSeconds
The execution role's ARN
The function's memory size
The deployment package format
33. Why should you keep Lambda functions stateless?
Lambda freely creates, reuses, and destroys execution environments based on traffic - you cannot predict or guarantee which environment (if any) will handle the next invocation, so any in-memory or local state from a previous call may or may not still be there.
Relying on that unpredictable reuse for correctness - like counting requests in a global variable and expecting an accurate total, or assuming a file written to /tmp will exist for the next invocation - leads to bugs that are hard to reproduce, since behavior differs between cold and warm invocations and across concurrent environments.
Designing handlers to be stateless means every invocation reads whatever state it needs from an external, durable store - DynamoDB, S3, ElastiCache, RDS - and writes results back the same way, so correctness doesn't depend on which environment happens to run it.
Global-scope variables and /tmp are still useful, but only as a performance optimization for caching (like a database connection or a downloaded reference file) - never as the sole source of truth.
Take quiz
Because /tmp storage is always deleted instantly
Because you can't guarantee the same execution environment handles the next invocation
Because global variables are illegal in Lambda
Because it violates the 15-minute timeout
In a global in-memory variable only
In an external durable store like DynamoDB or S3
In the function's environment variables
In the execution role
34. How do you optimize Lambda cold start times?
Cold-start optimization usually combines several smaller improvements rather than one silver bullet.
- Trim the deployment package - remove unused dependencies and split large libraries into layers only when actually needed.
- Initialize expensive objects outside the handler (SDK clients, DB connections) so they're created once per environment, not per invocation.
- Choose a faster-starting runtime where possible - interpreted runtimes like Node.js/Python typically cold-start faster than JVM-based ones.
- Use provisioned concurrency for latency-critical paths where cold starts are unacceptable.
- Use SnapStart (for supported runtimes like Java) to resume from a pre-initialized snapshot instead of running init from scratch.
- Avoid unnecessary VPC attachment, and when required, keep it simple since ENI/network setup adds a small but real overhead.
- Raise memory where the function is CPU-bound during init, since more memory also grants more CPU.
Measuring with the Init Duration field in CloudWatch Logs before and after each change is the only reliable way to confirm which optimizations actually move the needle for a specific function.
Take quiz
Creating SDK clients inside the handler on every call
Initializing SDK clients and connections outside the handler, in global scope
Increasing the deployment package size
Disabling CloudWatch Logs
Deleting the function's logs
Resuming execution from a pre-initialized snapshot instead of running init from scratch
Increasing the account concurrency limit
Disabling the execution role
35. What happens when a Lambda function exceeds its memory limit?
If a function tries to use more memory than its configured limit, Lambda terminates the execution environment immediately - the invocation fails, typically with a runtime error such as Runtime exited with error: signal: killed Runtime.ExitError, rather than a graceful exception your code can catch.
This is distinct from a timeout: memory exhaustion kills the process outright, and it can happen well before the configured timeout is reached if the workload is memory-hungry (large payload processing, big in-memory data structures, memory leaks across warm invocations).
For asynchronous or poll-based invocations, this failure is treated like any other function error and triggers the normal retry behavior for that invocation model; for synchronous callers, the error is returned immediately.
The Max Memory Used field in the CloudWatch Logs REPORT line, and the Memory Utilization insight (via Lambda Insights), are the standard signals for catching functions that are close to or hitting their memory ceiling before it causes production failures.
Take quiz
Automatically double the memory and continue
Terminate the execution environment and fail the invocation
Silently ignore the overage
Pause execution until memory frees up
Max Memory Used in the REPORT line
The function's ARN
The execution role's trust policy
The deployment package's checksum
36. Explain the execution flow of a Lambda function from invocation to response?
When a trigger calls Lambda, the service first checks for an available warm execution environment; if none exists, it provisions a new one (a cold start), which involves downloading the code, starting the runtime, and running any initialization code outside the handler.
sequenceDiagram
participant Client
participant LambdaService as Lambda Service
participant Env as Execution Environment
Client->>LambdaService: Invoke(event)
alt No warm environment
LambdaService->>Env: Create environment (Init phase)
Env->>Env: Download code, start runtime, run init code
end
LambdaService->>Env: Invoke phase - call handler(event, context)
Env->>Env: Execute handler logic
Env-->>LambdaService: Return result or error
LambdaService-->>Client: Response (sync) / ack (async)
Note over Env: Environment frozen, kept warm for reuse
Once the handler returns, Lambda sends the result back (immediately, for synchronous callers) and then freezes the environment rather than destroying it, hoping to reuse it for a subsequent invocation and skip the init phase next time.
If no new invocation arrives within an internal idle window, or a new code/version deployment supersedes it, the environment is eventually torn down, and the next request starts the cycle over as a fresh cold start.
Take quiz
Immediately destroys the execution environment every time
Freezes the environment, hoping to reuse it for future invocations
Restarts the entire AWS account
Deletes the function's code
Only running the handler's return statement
Downloading code, starting the runtime, and running init code outside the handler
Sending the final HTTP response to the client
Billing calculation only
37. Explain the internal working of the Lambda execution environment lifecycle?
Every execution environment passes through three defined phases, and understanding them is key to reasoning about performance and extension behavior.
| Phase | What happens |
| Init | Extensions initialize, the language runtime starts, and your code's static/global-scope initialization runs (imports, SDK client creation). |
| Invoke | The handler runs once per event; on a warm environment, this phase repeats directly without re-running Init. |
| Shutdown | Triggered when Lambda decides to reclaim the environment (inactivity, deployment update); extensions receive a SHUTDOWN event to clean up. |
Only the Invoke phase repeats across warm invocations - Init runs exactly once per environment's lifetime, which is precisely why moving expensive setup (DB connections, config loading) into global scope, outside the handler, pays off across many subsequent calls.
The environment itself is backed by a lightweight Firecracker microVM, giving strong isolation, and Lambda decides internally when to reuse versus recycle an environment based on traffic patterns, deployments, and internal maintenance - none of which your code can directly control or rely on.
Take quiz
Init
Invoke
Shutdown
None - all phases repeat equally
Only the billing system
Extensions, via a SHUTDOWN event, to clean up
The IAM execution role to revoke itself
CloudFront edge caches
38. How can you optimize Lambda function performance for high-throughput workloads?
High-throughput performance tuning spans configuration, code structure, and architecture choices working together.
- Right-size memory/CPU using AWS Lambda Power Tuning to find the cost/performance sweet spot rather than guessing.
- Reuse connections and clients (HTTP keep-alive, database connection pools) in global scope so warm invocations skip reconnect overhead.
- Batch where the trigger allows it - larger SQS/Kinesis batch sizes amortize per-invocation overhead across more records.
- Use provisioned concurrency to avoid throughput dips from cold starts during traffic ramps.
- Prefer Graviton (ARM) architecture where dependencies support it, for better price-performance.
- Avoid unnecessary synchronous chains - fan work out asynchronously (SQS, EventBridge) instead of one function blocking on another.
- Keep the deployment package lean so even the occasional cold start is fast.
Because these levers interact - bigger batches reduce invocation count but can raise per-invocation duration and risk timeouts - changes should be load-tested with realistic traffic rather than optimized in isolation.
Take quiz
x86_64 exclusively
Graviton (ARM64)
SPARC
PowerPC
Reducing invocation overhead by processing more records per call
Eliminating the need for an execution role
Guaranteeing zero cold starts
Disabling retries automatically
39. What is the difference between Lambda SnapStart and provisioned concurrency?
Both features target cold-start latency, but they solve it in fundamentally different ways.
| Aspect | SnapStart | Provisioned Concurrency |
| Mechanism | Caches a Firecracker microVM snapshot after one-time init, taken at publish, and resumes from it on cold start | Keeps a set number of full environments running and warm continuously |
| Runtime support | Originally Java; expanded to other managed runtimes over time (check current docs for coverage) | All runtimes |
| Cost model | Small per-restore charge, no charge for idle warm capacity | Billed continuously for the reserved warm capacity, whether invoked or not |
| Best fit | Functions with heavy, deterministic init (JVM class loading) where snapshotting removes most of that cost | Any latency-critical function needing guaranteed warm capacity at a known rate |
A subtlety with SnapStart: since the runtime resumes from a frozen snapshot, anything unique per environment that shouldn't be reused (like a cached random value or a rotated credential fetched during init) needs to be re-generated after resume, typically via the runtime hooks SnapStart provides for that purpose.
Take quiz
Resuming from a cached, pre-initialized microVM snapshot
Deleting unused layers automatically
Increasing the account concurrency limit
Forcing synchronous invocation only
It works identically for all randomness/unique state without any changes needed
State captured in the snapshot may need explicit re-initialization after resume
It removes the need for an execution role
It disables CloudWatch Logs
40. How does Lambda achieve isolation between concurrent executions?
Each concurrent invocation runs inside its own dedicated execution environment, which is backed by a lightweight, purpose-built virtual machine technology called Firecracker, developed by AWS specifically for secure, fast-booting, minimal-overhead sandboxing.
Firecracker microVMs give each environment its own isolated kernel, memory space, and virtualized devices - this is stronger isolation than a typical container alone provides, while still being lightweight enough to boot in milliseconds.
Within a single environment, Lambda guarantees that only one invocation runs at a time by default (the handler isn't re-entered concurrently), which is why scaling to more concurrent requests means creating more environments rather than sharing one across simultaneous invocations - the exception is response streaming and certain extension behaviors, which have their own concurrency nuances.
Each environment also gets its own ephemeral /tmp storage and network namespace, so state or a crash in one invocation's environment cannot leak into or affect another's.
Take quiz
Docker Swarm
Firecracker microVMs
Traditional full hardware VMs only
Kubernetes pods
Multiple concurrent invocations simultaneously
One invocation at a time before being freed for reuse
Zero invocations, ever
Only invocations from API Gateway
41. Explain the lifecycle of a Lambda execution context?
The execution context is the underlying environment (memory, /tmp, global variables, network connections) that persists across the Init phase and any number of subsequent Invoke phases, until Lambda decides to reclaim it.
stateDiagram-v2
[*] --> Created: New invocation, no warm env available
Created --> Initialized: Init phase (runtime + global code runs)
Initialized --> Invoking: Invoke phase (handler runs)
Invoking --> Frozen: Handler returns, env kept warm
Frozen --> Invoking: New invocation reuses this env
Frozen --> ShuttingDown: Idle timeout or new deployment
ShuttingDown --> [*]
Between invocations the environment is frozen, not destroyed - CPU is paused but state in memory and /tmp (up to 10 GB) survives, which is why global-scope caching (a DB connection, a downloaded config file) speeds up subsequent warm invocations.
Reclamation isn't predictable or guaranteed at any fixed time: AWS reclaims idle environments opportunistically, and publishing a new version or updating configuration always forces fresh environments rather than reusing old ones, since the old ones no longer match the current code.
Take quiz
Immediately destroyed and rebuilt
Frozen, retaining memory and /tmp state for potential reuse
Converted into an EC2 instance
Shared simultaneously across two functions
A new invocation using the exact same version
Publishing a new version or updating configuration
Reading an environment variable
Calling getRemainingTimeInMillis()
42. How do you implement idempotency in Lambda functions?
Because Lambda's underlying triggers (SQS, Kinesis, async retries) generally guarantee at-least-once delivery, the same event can legitimately reach your handler more than once - idempotency means designing the handler so processing it twice produces the same end result as processing it once.
- Extract or generate an idempotency key from the event - a message ID, an order ID, or a hash of the payload.
- Record processed keys in a durable store (commonly DynamoDB) using a conditional write (
ConditionExpression: attribute_not_exists(id)), so a duplicate key fails the write instead of reprocessing. - Store the original response alongside the key so a genuine retry can return the same cached result instead of redoing side effects.
- Set a TTL on the idempotency record so the table doesn't grow unbounded.
Rather than hand-rolling this, the AWS Lambda Powertools library (available for Python, Java, TypeScript, .NET) ships a ready-made idempotency utility that wraps a handler with exactly this DynamoDB-backed pattern, including handling in-flight duplicate requests safely.
Take quiz
Because Lambda guarantees exactly-once delivery for every trigger
Because many triggers deliver at-least-once, so the same event can arrive twice
Because idempotency is required by IAM policy syntax
Because it reduces the maximum memory setting
Ignoring all incoming event IDs
A conditional write on an idempotency key in a durable store like DynamoDB
Increasing the function's timeout to 15 minutes
Disabling CloudWatch Logs
43. Why doesn't increasing memory always reduce Lambda cost?
Lambda cost is calculated as allocated memory × billed duration (in GB-seconds) times the per-GB-second price, plus a small per-request fee - so raising memory raises the price rate for every millisecond billed.
For CPU-bound code, more memory also means more vCPU, so duration often drops enough to offset (or even beat) the higher rate - net cost can go down even though the price-per-ms went up.
For I/O-bound code - waiting on a network call, a database query, or an external API - extra CPU doesn't make the remote system respond any faster, so duration stays roughly flat while the price-per-ms still increases, making the invocation strictly more expensive with no performance benefit.
This is why blindly raising memory "to make things faster" can backfire on network-heavy functions; the reliable approach is benchmarking actual duration at multiple memory settings (with a tool like AWS Lambda Power Tuning) rather than assuming higher memory always helps.
Take quiz
Speeds up the network response time proportionally
Raises cost without meaningfully reducing duration
Automatically decreases the timeout
Has no effect on billing at all
Memory allocated multiplied by billed duration, plus a per-request fee
Only the number of layers attached
The function's programming language alone
The number of environment variables set
44. How does Lambda integrate with API Gateway for RESTful APIs?
The most common pattern is Lambda proxy integration, where API Gateway forwards the entire incoming HTTP request - method, headers, query string, path parameters, and body - as a single structured event object to the function, with no transformation in between.
The function is then responsible for returning a specifically shaped response object containing statusCode, headers, and a body string, which API Gateway passes straight back to the client.
def lambda_handler(event, context): return { "statusCode": 200, "headers": {"Content-Type": "application/json"}, "body": '{"message": "ok"}' }
API Gateway offers two API types for this: REST APIs, which are more feature-rich (usage plans, request validation, mapping templates for non-proxy integration) and HTTP APIs, which are simpler, lower-latency, and cheaper for straightforward Lambda-backed use cases.
A non-proxy (custom) integration is also possible, where API Gateway uses velocity mapping templates to transform the request before it reaches Lambda and the response afterward, but that adds configuration complexity that most teams avoid unless they need strict decoupling from Lambda's event shape.
Take quiz
Only a raw string with no structure
statusCode, headers, and body
An IAM policy document
A CloudFormation template
Slower and more expensive
Simpler, lower-latency, and cheaper for basic use cases
Incompatible with Lambda entirely
Only usable with Lambda@Edge
45. What is the difference between Lambda's event-driven model and a traditional server model?
A traditional server (a process on EC2, or a container that's always running) sits idle listening for requests continuously, holding memory and CPU reservation whether or not traffic is arriving, and you scale it by adding or resizing instances ahead of demand.
| Aspect | Lambda (event-driven) | Traditional server |
| Lifecycle | Ephemeral - created per burst of events, frozen/reclaimed after | Long-running, persistent process |
| Scaling trigger | Each incoming event, scaled automatically by the platform | Pre-provisioned capacity or reactive auto-scaling rules |
| Billing | Per request + execution time actually used | Per instance-hour regardless of utilization |
| State | Must be externalized - no guaranteed in-memory persistence | Can hold in-memory state naturally across requests |
The practical trade-off: event-driven Lambda removes idle-capacity waste and operational overhead for bursty or unpredictable workloads, while a traditional server model is often simpler to reason about (and can be cheaper) for steady, high, continuous load where near-constant utilization is expected.
Take quiz
Compute exists continuously whether or not events arrive
Execution environments are ephemeral, created and reclaimed around events
Billing is a flat monthly instance fee
State always persists reliably in memory forever
Traffic is bursty and unpredictable
Utilization is steady and consistently high
There is no traffic at all, ever
Requests never exceed 1 per day
46. How do you secure secrets used by a Lambda function?
The recommended approach is storing secrets in AWS Secrets Manager or Systems Manager Parameter Store (SecureString parameters), rather than hardcoding them or relying solely on plain environment variables, because both services support fine-grained IAM access control, encryption via KMS, and audit logging through CloudTrail.
Secrets Manager additionally supports automatic rotation for supported data stores (RDS, Redshift, DocumentDB) and custom rotation Lambda functions for others, so credentials can change without a manual redeploy.
import boto3, json _secrets_client = boto3.client("secretsmanager") _cached_secret = None def get_db_password(): global _cached_secret if _cached_secret is None: resp = _secrets_client.get_secret_value(SecretId="prod/db/password") _cached_secret = json.loads(resp["SecretString"])["password"] return _cached_secret
Caching the fetched secret in global scope (as above) avoids calling Secrets Manager on every warm invocation, which both reduces latency and avoids unnecessary API cost - combined with the function's execution role scoped to only that specific secret ARN, following least privilege.
Take quiz
It permanently disables encryption
It avoids re-fetching the secret on every warm invocation, reducing latency and API calls
It bypasses the need for an execution role
It automatically rotates the secret
Automatic rotation support for certain data stores
Unlimited free storage with no IAM controls
A guarantee of zero cold starts
Built-in Lambda@Edge replication
47. Explain how Lambda handles partial batch failures with SQS?
By default, if a Lambda function processing an SQS-triggered batch throws an error, the entire batch is considered failed and every message in it becomes visible again for reprocessing - even the ones that were actually handled successfully - risking duplicate side effects for those.
The fix is enabling ReportBatchItemFailures on the event source mapping's FunctionResponseTypes, which changes the contract: the handler must return an object listing only the message IDs that actually failed, and SQS will delete the successful ones and retry only the failed ones.
def lambda_handler(event, context): failures = [] for record in event["Records"]: try: process(record["body"]) except Exception: failures.append({"itemIdentifier": record["messageId"]}) return {"batchItemFailures": failures}
Without this feature enabled, teams often work around the problem by catching exceptions per-record and never letting the handler itself throw, but that pattern silently loses the ability to distinguish and re-queue only the truly failed messages, so ReportBatchItemFailures is the more correct and AWS-recommended fix.
Take quiz
Only that record to be retried
The entire batch to be retried, including already-successful records
The queue to be deleted
No retry at all
Nothing - the field is ignored
A batchItemFailures list containing only the failed message IDs
The full event unchanged
An HTTP status code
48. How can you monitor and debug Lambda functions in production?
Production observability for Lambda typically layers three tools together.
| Tool | What it gives you |
| CloudWatch Logs | Per-invocation logs plus the REPORT line (duration, billed duration, max memory used) |
| CloudWatch Metrics | Aggregate signals: Invocations, Errors, Throttles, Duration, ConcurrentExecutions |
| AWS X-Ray | Distributed trace showing time spent in the function versus downstream calls (DB, APIs) |
For deeper OS-level visibility (memory pressure, network usage per invocation) beyond what the REPORT line shows, Lambda Insights adds an extension that publishes enhanced metrics automatically.
Good practice on top of the built-in tooling includes structured JSON logging (so logs are queryable in CloudWatch Logs Insights), correlation IDs propagated across services for tracing a single request end-to-end, and CloudWatch Alarms on error rate, throttle count, and DLQ depth so problems surface before customers report them.
Take quiz
AWS X-Ray
Amazon Route 53
AWS Config
Amazon Cognito
Making logs queryable and filterable in CloudWatch Logs Insights
Reducing the function's memory allocation automatically
Disabling retries
Replacing the need for an execution role
49. What is the difference between Lambda extensions and Lambda layers?
A layer is a static packaging mechanism - a .zip of libraries or files extracted to /opt at Init time, purely to share dependencies or code across functions without bundling them into every deployment package.
An extension is an active, running process that lives alongside the runtime inside the execution environment and communicates with Lambda through the dedicated Extensions API, receiving lifecycle events (INIT, INVOKE, SHUTDOWN) so it can hook into the invocation lifecycle - for example, flushing telemetry right before shutdown, or enforcing a security check before the handler runs.
| Aspect | Layer | Extension |
| Nature | Static files/code | A running process with lifecycle hooks |
| Typical use | Shared libraries, custom runtimes | Monitoring/observability agents, security tooling |
| Types | N/A | Internal (in-process, same language) or external (separate process, any language) |
In practice, many monitoring vendors (Datadog, New Relic, Lumigo) ship their integration as an extension packaged inside a layer - the layer is the delivery mechanism, and the extension is the active behavior it enables.
Take quiz
An extension is a static zip file only, like a layer
An extension is an active process using lifecycle hooks via the Extensions API, while a layer is static content
Layers can only contain Python code
Extensions cannot be delivered inside a layer
A plain environment variable
A Lambda extension
A dead-letter queue
An IAM execution role
50. How does Lambda pricing work with the free tier and billing model?
Lambda pricing has two core components: a charge per million requests, and a charge per GB-second of compute (memory allocated × execution duration, rounded to the nearest 1ms), with optional additional charges for provisioned concurrency and data transfer.
| Component | How it's billed |
| Requests | Per invocation, counted per million requests |
| Duration | GB-seconds = memory (GB) × billed duration (seconds) |
| Provisioned concurrency (optional) | Billed per GB-hour for the reserved warm capacity, continuously |
The Lambda free tier - unlike many AWS free tiers that expire after 12 months - is perpetual: it includes 1 million free requests and 400,000 GB-seconds of compute per month, every month, for as long as the account exists (check current AWS pricing pages for exact figures, since AWS periodically updates them).
Because cost scales directly with memory × duration, the two biggest levers for cost efficiency are right-sizing memory (avoiding both under- and over-provisioning) and reducing actual execution time - which is why tools like AWS Lambda Power Tuning and profiling with X-Ray are so central to cost optimization, not just performance tuning.