SAA-C03Chapter 126 of 189Objective 3.3

Lambda Layers and Container Images

This chapter covers Lambda Layers and container images for AWS Lambda, two essential mechanisms for managing dependencies and runtime environments in serverless applications. For the SAA-C03 exam, understanding when to use layers versus container images, their limits, and how they interact with Lambda's execution model is critical. Approximately 5-10% of exam questions touch on Lambda configuration, including layers and container support, often in the context of optimizing deployment packages or migrating from zip-based functions.

25 min read
Intermediate
Updated May 31, 2026

Shipping Containers with Shared Toolkits

Imagine a large shipping company that transports goods worldwide. Each shipping container (Lambda function) is packed with cargo (application code). However, every container also needs certain tools like forklifts, pallet jacks, and barcode scanners (dependencies, libraries, configuration) to be unpacked at the destination. Instead of putting a full set of tools inside every single container (which wastes space and weight), the company creates standardized 'toolkits' (Lambda Layers) that are stored at each port (AWS managed or custom layers). When a container arrives, the port workers simply grab the required toolkit from the shelf and use it to handle the cargo. The container itself remains lightweight and only carries the unique cargo. If a toolkit needs to be updated (e.g., a new barcode scanner), the company updates the toolkit at the port once, and all containers that use that toolkit automatically benefit from the update. For exceptionally specialized cargo that requires a unique environment (e.g., a custom operating system or specific system libraries), the company packs the entire cargo inside a self-contained specialized container (container image) that includes everything needed, from the forklift to the driver. This is more flexible but heavier and takes longer to load. In AWS, Lambda Layers are the shared toolkits that reduce deployment package size and promote code reuse, while container images for Lambda are the self-contained environments that allow up to 10 GB of custom runtime and dependencies.

How It Actually Works

1. What Are Lambda Layers and Why Do They Exist?

Lambda Layers are a distribution mechanism for libraries, custom runtimes, and other function dependencies. They allow you to manage your function code separately from the dependencies it uses, reducing the size of the uploaded deployment package and making updates faster. Layers are essentially ZIP archives that are extracted into the /opt directory of the Lambda execution environment. Up to five layers can be attached to a function, including both custom layers and AWS-managed layers (e.g., AWS-Parameters-and-Secrets-Lambda-Extension). The total unzipped size of all layers plus the function code cannot exceed the Lambda deployment package size limit of 250 MB (unzipped) for zip-based functions.

Container images for Lambda, introduced in 2020, allow you to package your function code and dependencies as a Docker container image, up to 10 GB in size. This is useful when you have large dependencies (e.g., machine learning libraries) or need a custom runtime not provided by Lambda. The container image must implement the Lambda Runtime API, and you can use any base image (including AWS-provided base images for Python, Node.js, Java, etc., or community images).

2. How Lambda Layers Work Internally

When you create a Lambda function with layers, the following happens:

At deployment, AWS Lambda downloads all attached layers and extracts them into /opt in the execution environment. The extraction order is based on layer version ARN, with later versions potentially overwriting earlier ones. The function code is extracted into /var/task.

The function's runtime must be configured to look for libraries in /opt. For example, Python uses sys.path which includes /opt/python/lib/python3.9/site-packages; Node.js uses NODE_PATH; Java uses the classpath.

Layers are cached by the Lambda service across invocations to the same execution environment. However, if a layer is updated (new version), the next invocation will use the new layer, but existing execution environments may still use the old layer until they are recycled (typically after a few hours of inactivity).

Layer versions are immutable. Once you publish a layer version, you cannot change its content. You can delete a layer version, but functions using it will fail on next invocation (if the environment is recycled).

3. Key Components, Values, Defaults, and Timers

Maximum number of layers per function: 5 (including AWS-managed layers).

Maximum unzipped size for function code + layers: 250 MB.

Maximum zipped size for function code + layers: 50 MB (for direct upload) or 250 MB (via S3).

Container image size limit: 10 GB.

Layer version ARN format: arn:aws:lambda:region:account-id:layer:layer-name:version.

Layer permissions: You can grant access to other AWS accounts, or make the layer public. Permissions are per layer version.

Custom runtime layers: Must include a bootstrap file in /opt that handles the Lambda Runtime API. The runtime can be any executable (e.g., shell script, compiled binary).

Layer caching: Layers are cached on the execution environment for the lifetime of the environment (up to several hours). Updates to a layer version do not affect running environments until they are recycled.

4. Configuration and Verification Commands

To create a layer:

aws lambda publish-layer-version --layer-name my-layer \
    --description "My Python dependencies" \
    --zip-file fileb://layer.zip \
    --compatible-runtimes python3.9 python3.10 \
    --license-info "MIT"

To attach a layer to a function:

aws lambda update-function-configuration --function-name my-function \
    --layers arn:aws:lambda:us-east-1:123456789012:layer:my-layer:1

To list layers:

aws lambda list-layers
aws lambda list-layer-versions --layer-name my-layer

To create a container image for Lambda: 1. Create a Dockerfile that uses an AWS base image (e.g., public.ecr.aws/lambda/python:3.9) or a custom base image. 2. Copy your function code and dependencies. 3. Build and push to Amazon ECR:

docker build -t my-function .
docker tag my-function:latest <account-id>.dkr.ecr.us-east-1.amazonaws.com/my-function:latest
docker push <account-id>.dkr.ecr.us-east-1.amazonaws.com/my-function:latest
4.

Create the Lambda function with the image URI:

aws lambda create-function --function-name my-function \
    --package-type Image \
    --code ImageUri=<account-id>.dkr.ecr.us-east-1.amazonaws.com/my-function:latest \
    --role arn:aws:iam::123456789012:role/lambda-execution-role

5. How It Interacts with Related Technologies

IAM: Layers and container images do not have separate IAM policies. The function's execution role is used for accessing AWS resources. However, to pull container images from ECR, the Lambda service must have permissions (granted via the execution role or resource-based policy on ECR).

VPC: Functions using layers or container images can be placed in a VPC. The layer content is still extracted from AWS-managed S3 buckets, which requires internet access or VPC endpoints. Container images are pulled from ECR, which also requires VPC endpoints if the function is in a VPC.

CloudFormation: You can define layers and functions with container images in CloudFormation templates using AWS::Lambda::LayerVersion and AWS::Lambda::Function with PackageType: Image.

X-Ray: Layers can include the X-Ray SDK to enable tracing. Container images can include the X-Ray daemon as a sidecar process.

6. Exam-Relevant Details

Layer version immutability: You cannot modify a published layer version; you must publish a new version. Functions must be updated to point to the new version.

Layer deletion: Deleting a layer version does not affect functions already using it until the execution environment is recycled. However, you cannot create new functions using a deleted version.

Container image updates: To update a function using a container image, you must push a new image to ECR and update the function's image URI (or use the :latest tag and update the function). The Lambda service does not automatically pull new images; you must explicitly update the function.

Multi-architecture: Layers can be compatible with multiple architectures (x86_64, arm64). Container images can be built for a specific architecture.

Cost: Layers and container images are stored in S3 (for layers) and ECR (for images). You pay for storage and data transfer. There is no additional charge for using layers or container images beyond the standard Lambda pricing.

Walk-Through

1

Create a Lambda Layer

First, package your dependencies into a ZIP file with the correct directory structure. For Python, the structure is `python/lib/python3.9/site-packages/` (or `python/` for the root). For Node.js, it's `nodejs/node_modules/`. For Java, it's `java/lib/`. Then, use the AWS CLI or console to publish the layer version. Specify compatible runtimes and architectures. The layer is stored in S3 in the same region. You can optionally add a license and description. The layer version ARN is returned.

2

Attach Layer to a Function

Update the Lambda function configuration to include up to five layer version ARNs. The order matters: if two layers provide the same file, the one listed later takes precedence. The function's code is extracted into `/var/task`, and layers into `/opt`. The runtime must include `/opt` in its library search path. After attaching, the next invocation uses the new layers. Existing execution environments may still use old layers until recycled.

3

Build Container Image

Create a Dockerfile that starts from an AWS base image (e.g., `public.ecr.aws/lambda/python:3.9`) or a custom base image that implements the Runtime API. Copy your function code and dependencies. The CMD or ENTRYPOINT must point to the function handler. Build the image with `docker build`. Tag it with the ECR repository URI and push it to Amazon ECR using `docker push`.

4

Create Function from Container Image

When creating the Lambda function, set `PackageType` to `Image` and provide the ECR image URI. The function's handler is defined in the image (via CMD or ENTRYPOINT). The image must be in the same region as the function. Lambda will pull the image from ECR on first invocation and cache it on the execution environment. Subsequent invocations reuse the cached image until the environment is recycled.

5

Update Container Image

To update a function using a container image, you must push a new image to ECR (either by updating the same tag, e.g., `:latest`, or a new tag). Then, update the function's code with the new image URI. If you use `:latest`, you must still call `update-function-code` to trigger Lambda to pull the new image. Lambda does not automatically detect image updates. After updating, new execution environments use the new image; old ones continue with the old image until recycled.

What This Looks Like on the Job

Enterprise Scenario 1: Machine Learning Inference with Large Dependencies

A financial services company develops a serverless application for real-time fraud detection using a TensorFlow model. The model and its dependencies (TensorFlow, NumPy, pandas) exceed the 250 MB unzipped limit for zip-based Lambda functions. They decide to use a container image for Lambda. They create a custom Docker image based on the AWS-provided Python 3.9 image, install the required libraries, and copy the model file. The image size is 1.5 GB, well within the 10 GB limit. They push the image to Amazon ECR and create a Lambda function with 10 GB memory and a 15-minute timeout. The function is triggered by an API Gateway endpoint. In production, they use multiple versions of the image for A/B testing. A common misconfiguration is forgetting to update the function code after pushing a new image, causing the function to use an outdated model. They set up a CI/CD pipeline using AWS CodeBuild and CodePipeline to automatically update the function after a successful image push.

Enterprise Scenario 2: Shared Dependencies Across Multiple Functions

A media company has dozens of Lambda functions that process video files, generate thumbnails, and transcode content. All functions use the same set of FFmpeg binaries and Python libraries. To avoid duplicating these dependencies in each function's deployment package, they create a single Lambda layer containing FFmpeg and the common libraries. They publish the layer and attach it to all relevant functions. When FFmpeg is updated, they publish a new layer version and update each function's configuration to point to the new version. This reduces deployment package sizes from 50 MB to under 1 MB, speeding up deployments. They also use the layer for environment-specific configurations (e.g., database connection strings) by placing a config file in the layer and using environment variables to select the correct one. A pitfall is that the layer's unzipped size plus the function code must stay under 250 MB; they monitor this with CloudWatch metrics.

Enterprise Scenario 3: Custom Runtime for Legacy Application

A government agency has a legacy application written in COBOL that needs to be migrated to serverless. They create a custom runtime layer that includes a COBOL interpreter and a bootstrap script that implements the Lambda Runtime API. The bootstrap script reads the event from stdin, passes it to the COBOL program, and writes the response to stdout. They package the interpreter and the bootstrap in a layer, and the COBOL source code as the function code. This allows them to run COBOL code on Lambda without modifying the original program. The layer is compatible with the provided.al2 runtime. They test the layer locally using the Lambda Runtime Interface Emulator (RIE). The main challenge is ensuring the bootstrap handles all Lambda lifecycle events correctly (e.g., shutdown signals for graceful termination).

How SAA-C03 Actually Tests This

SAA-C03 Exam Focus on Lambda Layers and Container Images

The SAA-C03 exam tests your understanding of when to use Lambda Layers versus container images, their limits, and how they affect function behavior. Key objectives under Domain 3 (High Performance) and specifically Objective 3.3: "Optimize deployment and operations" include:

Identifying scenarios where layers reduce deployment size and speed up updates.

Understanding the 250 MB unzipped limit for zip-based functions (including layers) and the 10 GB limit for container images.

Knowing that layers are extracted to /opt and function code to /var/task.

Recognizing that container images require the Lambda Runtime API and are pulled from ECR.

Common Wrong Answers and Traps

Trap 1: "Layers can be used to share code across functions without versioning." Candidates think layers are dynamic and updates propagate automatically. Reality: Layer versions are immutable; you must publish a new version and update the function. The exam tests understanding that layers do not auto-update.

Trap 2: "Container images for Lambda can be stored in any container registry, including Docker Hub." Candidates assume any registry works. Reality: Container images must be stored in Amazon ECR in the same region as the function. The exam may include options like "ECR Public" (which is allowed) or "Docker Hub" (which is not).

Trap 3: "You can attach up to 10 layers to a function." The limit is 5 layers. The exam often tests this exact number.

Trap 4: "Using a container image eliminates the need for a Lambda execution role." Candidates think containers handle permissions. Reality: The function still needs an execution role for accessing AWS services (e.g., ECR, DynamoDB). The role is required regardless of packaging type.

Trap 5: "Layers can be updated in place without creating a new version." This is false. Layer versions are immutable. The exam tests that you must publish a new version and update the function's layer list.

Specific Numbers and Terms

250 MB unzipped limit for zip functions (including layers).

50 MB zipped limit for direct upload, 250 MB via S3.

10 GB container image limit.

5 layers per function.

Layer extraction path: /opt.

Function code path: /var/task.

Container image must implement the Runtime API (via a bootstrap or entrypoint).

AWS provides base images for Python, Node.js, Java, .NET, Go, Ruby, and custom (provided.al2).

Edge Cases and Exceptions

If a function uses both layers and a container image? Not possible: a function is either zip-based (with layers) or image-based (no layers).

Layer permissions can be granted to another account or made public. The exam may ask how to share a layer across accounts.

For container images, if the image is in a different account, you need cross-account ECR permissions.

The Lambda execution environment caches layers and images; updates may not take effect until the environment is recycled (typically after 15 minutes of inactivity).

How to Eliminate Wrong Answers

If a question mentions sharing code across functions and reducing deployment size, think layers.

If a question mentions large dependencies (e.g., ML models) or custom runtimes, think container images.

If a question mentions updating dependencies without redeploying the function code, layers are the answer.

If a question mentions a 10 GB limit, it's container images; 250 MB is the zip limit.

Always check the number of layers: maximum 5.

Key Takeaways

Lambda Layers allow you to share code and dependencies across functions, reducing deployment package size and enabling faster updates.

Layer versions are immutable; you must publish a new version and update the function to use it.

The maximum unzipped size for a function plus all layers is 250 MB; the maximum zipped size for direct upload is 50 MB, or 250 MB via S3.

Container images for Lambda support up to 10 GB and must implement the Lambda Runtime API; they are stored in Amazon ECR in the same region.

A function can use either layers (zip-based) or a container image, not both.

The execution environment caches layers and images; updates may not take effect until the environment is recycled (typically after 15 minutes of inactivity).

You can attach up to 5 layers to a function, including AWS-managed layers.

Easy to Mix Up

These come up on the exam all the time. Here's how to tell them apart.

Lambda Layers

Maximum unzipped size: 250 MB (including function code)

Up to 5 layers per function

ZIP archive extracted to /opt

Supports multiple runtimes (Python, Node.js, etc.)

Faster deployment updates (only metadata change)

Container Images

Maximum image size: 10 GB

No layer support (self-contained)

Docker image pulled from ECR

Any runtime or custom environment (via Runtime API)

Slower deployment (image push and pull)

Watch Out for These

Mistake

Lambda layers are automatically updated when you update the layer.

Correct

Layer versions are immutable. You must publish a new version and explicitly update the function's layer configuration to point to the new version. Existing execution environments continue using the old version until recycled.

Mistake

Container images for Lambda can be stored in any Docker registry.

Correct

Container images must be stored in Amazon ECR in the same AWS region as the Lambda function. Other registries like Docker Hub or self-hosted registries are not supported.

Mistake

You can attach up to 10 layers to a Lambda function.

Correct

The maximum number of layers per function is 5, including AWS-managed layers. This includes both custom and AWS layers.

Mistake

Using a container image for Lambda eliminates the need for an IAM execution role.

Correct

The Lambda function still requires an execution role to access AWS resources (e.g., ECR, DynamoDB, S3). The role is attached to the function, not the image.

Mistake

Layers can be shared across accounts without any special configuration.

Correct

To share a layer across accounts, you must grant permissions to the target account using the `add-layer-version-permission` API. The layer can be made public by granting permission to `*`.

Do You Actually Know This?

Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.

Frequently Asked Questions

What is the difference between Lambda Layers and container images?

Lambda Layers are ZIP archives that contain libraries and dependencies, extracted into /opt. They are attached to zip-based functions and count toward the 250 MB unzipped limit. Container images are Docker images up to 10 GB that include the function code and all dependencies, stored in ECR. They are used with image-based functions and cannot use layers. Choose layers for smaller, shared dependencies; choose container images for large dependencies or custom runtimes.

How do I update a Lambda function that uses a container image?

You must push a new image to Amazon ECR (with a new tag or overwrite the existing tag). Then, update the Lambda function's code by calling update-function-code with the new image URI. Lambda does not automatically pull new images; you must explicitly trigger the update. After updating, new execution environments use the new image; old ones continue with the old image until recycled.

Can I use Lambda Layers with a container image?

No. A Lambda function is either zip-based (which can use layers) or image-based (which cannot). Image-based functions are self-contained; all dependencies must be included in the container image. You cannot attach layers to an image-based function.

How do I share a Lambda Layer across AWS accounts?

Use the add-layer-version-permission API to grant permissions to another account or make the layer public. For example: aws lambda add-layer-version-permission --layer-name my-layer --version-number 1 --statement-id xaccount --principal 123456789012 --action lambda:GetLayerVersion. The principal can be an account ID or '*' for public.

What happens if I delete a Lambda Layer version that is in use?

Existing execution environments that have already loaded the layer will continue to work until they are recycled. However, you cannot create new functions or update existing ones to use the deleted version. Any new invocation that requires a fresh environment will fail because the layer version is unavailable.

What is the maximum size of a Lambda deployment package for zip-based functions?

The maximum unzipped size (including all layers) is 250 MB. The maximum zipped size for direct upload via the console or CLI is 50 MB. If the zipped package is larger than 50 MB, you must upload it to Amazon S3 and specify the S3 location when creating or updating the function.

Can I use a custom runtime with Lambda Layers?

Yes. You can create a custom runtime layer that includes a bootstrap file and any dependencies. The bootstrap must implement the Lambda Runtime API. Set the function's runtime to 'provided' or 'provided.al2'. The layer is extracted to /opt, and the bootstrap must be executable and located at /opt/bootstrap.

Terms Worth Knowing

Ready to put this to the test?

You've just covered Lambda Layers and Container Images — now see how well it sticks with free SAA-C03 practice questions. Full explanations included, no account needed.

Done with this chapter?