The Dependency Packaging Problem
Imagine you have 50 Lambda functions that all use the pandas data processing library (which is ~50 MB compressed) and your company's internal audit-logger module. Without Layers, every function's deployment package must include these dependencies. Your CI/CD pipeline uploads 50 × 50 MB = 2.5 GB of identical bytes on every deployment. Deployments are slow, S3 costs accumulate, and updating pandas requires redeploying all 50 functions.
How Layers Work
A Lambda Layer is a ZIP archive that is mounted into the execution environment's filesystem at /opt. Your function code can then import from /opt as if the libraries were installed locally.
/opt/
├── python/ ← Python packages go here (auto-added to sys.path)
│ └── lib/
│ └── python3.12/
│ └── site-packages/
│ ├── pandas/
│ └── numpy/
└── bin/ ← Executables (e.g., ffmpeg, chromium)
└── ffmpeg
Creating and publishing a Layer: you install the dependencies into the directory structure the runtime expects, zip it up, and publish it through the Lambda API — which returns a versioned Layer ARN. Attaching the Layer to a function is then a single configuration update that points the function at that ARN.
Key constraints:
- Maximum 5 layers per function.
- Total unzipped size of function code + all layers must not exceed 250 MB.
- Layers are immutable — publishing a new version creates a new ARN. Functions pin to a specific layer version, giving you reproducible deployments.
- Layers can be shared across accounts by setting a resource-based policy, enabling platform teams to publish internal libraries for all teams to consume.
Senior depth — the /opt path matters by runtime: Python automatically adds /opt/python and /opt/python/lib/pythonX.Y/site-packages to sys.path. Node.js adds /opt/nodejs/node_modules. Java requires you to set the CLASSPATH environment variable. If your layer isn't being found, the directory structure inside the ZIP is almost always the cause.