Serverless Package Individually

Serverless Package Individually: A Practical Guide

Overview

The package.individually: true setting in the Serverless Framework enables separate packaging for each AWS Lambda function, optimizing deployment size and improving performance, below images show the difference for function view before and after.

Key Benefits

  • Smaller Packages: Each function includes only required dependencies
  • Faster Deployments: Only modified functions need to be uploaded
  • Better Performance: Reduced cold start times and memory usage
  • Easier Maintenance: Simplified dependency management per function

Implementation Example

service: ts-test
frameworkVersion: "3"
useDotenv: true

provider:
  name: aws
  runtime: nodejs20.x
  stage: ${opt:stage, 'dev'}
  region: ap-south-1
  environment:
    REGION: ap-south-1
    STAGE: ${self:provider.stage}

functions:
  view:
    handler: src/handlers/view.handler
    events:
      - http:
          path: /view
          method: get
          cors: true
  details:
    handler: src/handlers/details.handler
    events:
      - http:
          path: /details
          method: get
          cors: true

plugins:
  - serverless-esbuild
  - serverless-offline

custom:
  esbuild:
    bundle: true
    minify: false
    sourcemap: true
    exclude: ["aws-sdk"]
    target: "node20"
    platform: "node"
    concurrency: 10

package:
  individually: true

Directory Structure

project/
├── src/
│   ├── handlers/
│   │   ├── view.ts
│   │   └── details.ts
│   └── shared/
│       └── utils.ts
├── package.json
└── serverless.yml

Performance Impact

Without package.individually

  • Single large deployment package (~20MB)
  • Longer cold starts
  • All functions share same deployment package

With package.individually

  • Smaller individual packages (~2-5MB)
  • Faster cold starts
  • Function-specific deployments

Best Practices

  1. Dependency Management

    • Use shared layers for common dependencies
    • Regular dependency cleanup
    • Only include required files
  2. Deployment Optimization

    package:
      patterns:
        - "!node_modules/**"
        - "src/shared/**"
        - "!test/**"
    
  3. Build Configuration

    • Use esbuild for faster builds
    • Enable minification in production
    • Exclude AWS SDK

Build Optimization with ESBuild

For production deployments, you can enable additional optimizations:

custom:
  esbuild:
    bundle: true
    minify: ${self:provider.stage == 'prod', false}  # Minify only in production
    sourcemap: false  # Disable sourcemaps in production
    exclude: ["aws-sdk"]
    target: "node20"
    platform: "node"
    concurrency: 10    # Concurrent builds
    treeShaking: true  # Remove unused code

Common Issues and Solutions

  1. Large Packages

    • Enable minification
    • Remove unnecessary dependencies
    • Use proper exclusion patterns
  2. Slow Deployments

    • Enable concurrent builds
    • Optimize shared code
    • Use proper region selection

Quick Start

  1. Add package.individually: true to serverless.yml
  2. Configure esbuild for optimization
  3. Run serverless deploy
4 Likes