AWS Lambda
Lambda Layers
Import Libraries
Serverless Computing
Cloud Functions

Import libraries in lambda layers

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

AWS Lambda layers let you package shared dependencies separately from your function code, but importing libraries from a layer only works if the layer has the directory structure Lambda expects. For Python functions, the usual rule is simple: put the installed packages under a top-level python/ directory in the layer zip, attach the layer to the function, and then import the libraries normally in your handler.

The Expected Python Layer Structure

For Python runtimes, Lambda automatically adds the layer's python/ directory to the import path. That means a valid layer zip typically looks like this:

text
1layer.zip
2└── python/
3    ├── requests/
4    ├── urllib3/
5    └── certifi/

A practical build flow is:

bash
mkdir -p python
pip install requests -t python/
zip -r layer.zip python

After you publish the layer and attach it to a function, your function code can simply do:

python
1import requests
2
3
4def lambda_handler(event, context):
5    response = requests.get("https://example.com", timeout=5)
6    return {"status_code": response.status_code}

There is no special import from layer syntax. If the layer is packaged correctly, normal imports work.

Publishing the Layer

Once the zip file is ready, publish it:

bash
1aws lambda publish-layer-version \
2  --layer-name requests-layer \
3  --zip-file fileb://layer.zip \
4  --compatible-runtimes python3.12

Then attach the resulting layer version ARN to your function in the console, CloudFormation, SAM, Terraform, or the CLI.

The important point is that a layer version is immutable. If dependencies change, publish a new layer version rather than modifying the old one in place.

Why Packaging Fails So Often

Most Lambda layer import failures are packaging problems, not Python import problems.

Common causes include:

  • the zip does not contain a top-level python/ directory
  • packages were installed into the wrong folder
  • the layer was built for the wrong Python version
  • native dependencies were compiled on an incompatible operating system

If the layout is wrong, Lambda cannot discover the library on the runtime import path.

Native Dependencies Need Compatible Builds

Pure Python packages are the easy case. Native dependencies are stricter.

For example, a package with compiled extensions may work when zipped from your laptop and still fail in Lambda because the binary was built for macOS or Windows instead of the Linux environment Lambda actually runs.

In those cases, build the layer in an environment compatible with the target Lambda runtime, such as:

  • Amazon Linux compatible build containers
  • AWS SAM build workflows
  • CI jobs that match the Lambda runtime architecture

This issue becomes even more important when CPU architecture matters, such as x86_64 versus arm64.

Keep Layers Focused

A layer should group dependencies that genuinely belong together. Good candidates are:

  • shared HTTP libraries
  • internal utility packages
  • database clients reused across many functions

Bad candidates are giant "everything" layers that bundle unrelated dependencies for convenience. Those become hard to version, slow to build, and awkward to reuse.

If only one function uses a dependency, it may be simpler to package that dependency directly with the function instead of creating layer complexity.

Layer Versus Function Package

Layers are useful when:

  • several functions share the same library set
  • deployment size is easier to manage when dependencies are separated
  • you want to update shared libraries independently of function code

Direct packaging is simpler when:

  • only one function needs the dependency
  • the dependency set changes often with the function
  • the operational overhead of layer versioning is not worth it

The right choice is not always "use layers." It is "use layers when sharing and versioning actually help."

Troubleshooting Imports

If import requests fails even though the layer is attached, check these first:

  1. unzip the layer locally and verify the top-level python/ directory exists
  2. confirm the package directory lives under that path
  3. verify the layer runtime matches the function runtime
  4. verify compiled dependencies were built for the Lambda target platform

A quick debugging trick is to inspect sys.path inside the function:

python
1import sys
2
3
4def lambda_handler(event, context):
5    return {"python_path": sys.path}

If the expected layer path is missing, the issue is attachment or packaging rather than the library itself.

Common Pitfalls

The biggest mistake is zipping the package contents directly without the top-level python/ directory. Lambda will not place those files on the expected Python import path.

Another issue is building dependencies on a machine whose OS or architecture does not match the Lambda runtime, which breaks native extensions.

Developers also often treat layers as a universal best practice. If a dependency is function-specific and changes constantly, direct packaging may be simpler.

Finally, remember that attaching the wrong layer version is effectively the same as attaching the wrong dependency set. Layer versions are explicit, so check the ARN carefully.

Summary

  • For Python Lambda layers, package dependencies under a top-level python/ directory.
  • Publish the layer, attach it to the function, and import the library normally in code.
  • Most import failures come from incorrect zip structure or incompatible native builds.
  • Build native dependencies for the actual Lambda runtime environment.
  • Use layers when shared dependencies and independent versioning are worth the extra operational complexity.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.