How to Reduce AWS Lambda Cold Start Times by Shrinking Deployment Package Size
AWS Lambda cold starts are a common pain point for engineers.
This article highlights a practical way to reduce cold start times: keep your deployment package as small as possible.
Why Package Size Matters for Cold Starts
Whenever an AWS Lambda function experiences a cold start, the code package (sometimes a ZIP archive) is downloaded from S3. The smaller the package, the faster the initialization — that’s basic physics.
Furthermore, Lambda enforces a strict 250MB unzipped deployment size limit, and direct uploads are capped at 50MB zipped. Anything larger requires uploading to S3, adding friction to your CI/CD pipeline.
Besides performance, minimizing package size accelerates deployments, reduces the attack surface, and can even improve your CI/CD feedback loop. This principle also applies to Lambda Layers and container-based deployments. Leaner is always better.
Step 1: Audit Your Lambda Deployment Package
First, verify what’s inside your ZIP. Is your code package larger than you expected?
You can download the deployed ZIP from the AWS Lambda console and inspect its contents. On macOS, the following command summarizes directory sizes post-extraction:
du -sh * 2>/dev/null | sort -hr
Step 2: Find Your Biggest Functions (with AWS Config Advanced Query)
If you want to identify oversized Lambdas across accounts, leverage AWS Config Advanced Query:
SELECT
accountId,
resourceId,
configuration.codeSize,
WHERE
resourceType = 'AWS::Lambda::Function'
AND configuration.codeSize > 123456789 -- bytes
ORDER BY
configuration.codeSize desc
You can also use observability tools like Datadog to monitor Lambda function package sizes in bytes, making it easier to spot unusually large deployments across your environment.
Watch out for functions with identical sizes down to the byte. This can indicate misconfigured deployments or duplicate artifacts.
Step 3: Tips for Reducing Deployment Size
Let’s break down optimization tips using TypeScript (Node.js) and Python, two of the most popular Lambda languages.
Audit Your Development Dependencies
Development-only binaries (like mypy) can easily sneak into your production package, sometimes eating up 50MB or more. Even with separate requirements.txt files for dev and prod, transitive dependencies (e.g., via SQLAlchemy) may still bloat your deploy. Always verify your artifacts using both manual inspection and your package manager’s tree/list commands.
Watch Out for Duplicate or Monolithic Artifacts
It’s surprisingly common to see multiple Lambda functions with different names but identical, oversized packages — especially in monorepos. This usually signals a broken build step or poorly configured packaging logic.
Dependency Resolution Pitfalls
We’ve seen cases where multiple versions of native libraries (like OpenSSL) are bundled, doubling the size. Audit your dependencies carefully.
For TypeScript: Apply Frontend Optimization Practices
Never deploy raw code. Always bundle with tools like esbuild.
Backend engineers unfamiliar with frontend practices often overlook this, resulting in massive unoptimized bundles. Use bundle analyzers (e.g., webpack-bundle-analyzer) to visualize and shrink your output.
Prefer ES Modules (ESM) over CommonJS, as ESM tends to produce smaller, more efficient bundles.
Find and Remove Unused Code with Knip
Knip is a tool that scans your TypeScript (and JavaScript) projects to detect unused files, exports, and dependencies.
Use it to keep your Lambda artifacts minimal and free from dead code:
npx knip # npm
pnpx knip # pnpm
bunx knip # bun
Review the report, and safely remove what you don’t need. This will help shrink your deployment package and reduce the attack surface.
Watch the e18e Initiative
For cutting-edge improvements in Node.js ecosystem package size and startup performance, keep an eye on the e18e initiative. They are working on reducing polyfills, minimizing legacy code, and supporting more efficient modules. While not specifically aimed at serverless, these improvements naturally benefit AWS Lambda and similar environments.
For Python: The .py Purge
Python loads .pyc bytecode, so you can safely delete all .py source files from your ZIP after compilation:
python -m compileall -b .
find . -name "*.py" -delete
The tradeoff: tracebacks won’t show the original source. For production workloads (especially third-party modules), this is usually acceptable — proper error handling matters more than debugging tracebacks.
Automate This in CDK
If you use AWS CDK, hook this cleanup into your deployment pipeline for repeatable results.
Node.js 22+: enableCompileCache
Starting with Node.js 22, you can use enableCompileCache().
This leverages V8’s code cache and stores cached bytecode in temporary files.
While I haven’t benchmarked the impact on Lambda yet, enabling this option could potentially improve performance if your deployment environment supports it.
Final Thoughts
AWS Lambda’s abstraction is powerful, but it’s easy to overlook deployment hygiene.
Trimming your deployment size is one of the simplest, highest-leverage optimizations for cold start latency, security, and operational agility — not just for Lambda, but for all serverless platforms.
Less is more. Audit, optimize, and delete ruthlessly.