AWS Lambda Layers: The Dependency Management Pattern You Should Be Using

AWS Lambda Layers: The Dependency Management Pattern You Should Be Using
7 views

Most Lambda functions bundle every dependency into the deployment ZIP. A simple Node.js function that uses aws-sdk, lodash, and moment ends up as a 15MB package. Lambda Layers move shared dependencies out of your function package permanently — reducing cold starts, deployment time, and operational complexity simultaneously. This guide focuses on AWS Lambda layers, with the production trade-offs senior engineers need to make sound decisions.

⚡ TL;DR: Lambda Layers are ZIP files containing libraries that get mounted at /opt in the Lambda execution environment. Your function code references them without bundling them. Each function can use up to 5 layers. Layers are versioned and sharable across functions and accounts.

Why Layers Dramatically Reduce Cold Starts

# Without layers:
# your-function.zip = your code (50KB) + dependencies (45MB)
# Every deployment = 45MB upload
# Every cold start = download + extract 45MB

# With layers:
# your-function.zip = your code only (50KB) 
# layer.zip = dependencies (45MB) — deployed ONCE, shared across functions
# Cold start: Lambda already has layer cached from previous invocation

# Real-world cold start reduction:
# Before layers: 2.8s cold start (downloading 45MB package)
# After layers:  1.1s cold start (60KB function + pre-cached layer)
# Improvement:  61% faster cold start

Creating a Lambda Layer (Node.js)

# Layer structure MUST follow this exact directory layout:
mkdir -p my-layer/nodejs
cd my-layer/nodejs

# Install only production dependencies
npm init -y
npm install lodash axios moment --production

# Package the layer
cd ..
zip -r my-layer.zip nodejs/

# Deploy via AWS CLI
aws lambda publish-layer-version \
  --layer-name "common-dependencies" \
  --description "Shared Node.js dependencies" \
  --zip-file fileb://my-layer.zip \
  --compatible-runtimes nodejs18.x nodejs20.x

# Response includes LayerVersionArn:
# arn:aws:lambda:us-east-1:123456789:layer:common-dependencies:1

Using Layers in Your Function

// Lambda mounts layer contents at /opt/
// Node.js layer at /opt/nodejs/node_modules/
// Python layer at /opt/python/ or /opt/python/lib/python3.x/site-packages/

// In your function code — just require normally:
const _ = require('lodash');    // Loaded from /opt/nodejs/node_modules/lodash
const axios = require('axios'); // Same

// Your function ZIP contains ONLY your code:
// index.js (2KB) — not node_modules!

exports.handler = async (event) => {
  const data = await axios.get(event.url);
  return _.pick(data.data, ['id', 'name', 'email']);
};

SAM / CloudFormation Layer Configuration

# SAM template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Globals:
  Function:
    Layers:
      - !Ref CommonDependenciesLayer  # All functions share this layer
    Runtime: nodejs20.x
    Timeout: 30

Resources:
  CommonDependenciesLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      LayerName: common-dependencies
      ContentUri: layers/common/
      CompatibleRuntimes:
        - nodejs20.x
      RetentionPolicy: Retain  # Keep old versions for rollback

  UserFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: src/user/  # Only your code — no node_modules
      Handler: index.handler

  OrderFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: src/order/  # Shares the same layer

Layer Best Practices

# Layer size limits:
# Unzipped: 250MB per function (all layers combined)
# Zipped: 50MB per layer

# Best practice: split by update frequency
# Layer 1: slow-changing dependencies (aws-sdk, lodash) — update monthly
# Layer 2: fast-changing internal libs — update weekly
# Function: your code — update multiple times daily

# Share layers across accounts (useful for org-wide shared libs):
aws lambda add-layer-version-permission \
  --layer-name common-dependencies \
  --version-number 1 \
  --statement-id allow-org \
  --action lambda:GetLayerVersion \
  --principal "*" \
  --organization-id o-xxxxx

# Reference specific layer version for reproducibility:
# Never use :latest alias in production — always pin to version number

Lambda Layers Cheat Sheet

  • ✅ Node.js layers go in nodejs/node_modules/ — exact path matters
  • ✅ Python layers go in python/ or python/lib/python3.x/site-packages/
  • ✅ Always pin to specific layer version in production
  • ✅ Use RetentionPolicy: Retain for rollback capability
  • ✅ Split by update frequency — stable deps in one layer, internal libs in another
  • ✅ Layers are regional — deploy to each region you use
  • ❌ Don’t bundle dependencies in both layer AND function ZIP
  • ❌ Don’t put secrets in layers — use Parameter Store or Secrets Manager

Lambda Layers work best alongside the cold start optimization techniques — layers reduce package download time while SnapStart and ARM64 reduce initialization time. For monitoring your layer impact, the CloudWatch Insights query guide shows how to measure cold start reduction before and after layer adoption. Official reference: AWS Lambda Layers documentation.

Master AWS Lambda architecture patterns

→ View Course on Udemy — Hands-on video course covering every concept in this post and more.

Sponsored link. We may earn a commission at no extra cost to you.

Related: AWS Lambda Best Practices: Write Functions That Scale and Never Time Out · Lambda Versioned Layers: Native Node Addons Without ABI Surprises · AWS Lambda SnapStart: Sub-100ms Cold Starts for Java Without Changing Your Code

Watch: 100 Days of AI on YouTube

Short videos from CheatCoders, one AI engineering topic per day.

Open the playlist on YouTube · CheatCoders on YouTube

Deep-dive PDF

Get the expanded guide for this post — extra diagrams-style checklists, failure modes, and a production walkthrough. Free when you subscribe to CheatCoders.

Already subscribed? or open the subscribe page.


Discover more from CheatCoders

Subscribe to get the latest posts sent to your email.

Comments

No comments yet. Why don’t you start the discussion?

Leave a comment

No account needed. Name and email are optional.