AWS Builder Center
AWS Lambda Self-Managed S3 Code Storage: `COPY` vs. `REFERENCE`

AWS Lambda Self-Managed S3 Code Storage: `COPY` vs. `REFERENCE`

AWS Lambda now supports self-managed S3 code storage for ZIP deployments. This article explains COPY vs. REFERENCE modes, setup requirements, deployment limits, and performance test results.

Cloud Architect | Passionate About Serverless and AI
On July 15, 2026, AWS announced a new option for storing AWS Lambda deployment packages: self-managed Amazon S3 code storage.

How Lambda stored deployment packages before

Before this release, Lambda copied every  .zip  deployment package into Lambda-managed storage, even when the source file was already in Amazon S3.
This storage was limited to 75 GB per account and region, so teams with many functions, versions, and layers could eventually encounter a CodeStorageExceededException and need a quota increase.
With this release, AWS has made the following changes
  • Default Lambda managed storage quota has been increased to 300 GB per account and region
  • There are now 2 code storage modes for Lambda
  • COPY - Lambda copies the .zip file into its own storage (Will count against the 300 GB per region/account).
  • REFERENCE -Lambda references the  .zip  file directly from your S3 bucket without creating a Lambda-managed copy.

What this feature does not change

Self-managed S3 code storage changes where Lambda stores deployment packages, but the existing deployment limits still apply:
  • Deployment package size: The unzipped package cannot exceed 250 MB.
  • Container images: Self-managed S3 code storage applies only to  .zip -based functions and layers.

Testing  REFERENCE  mode

To understand how  REFERENCE  mode works, I tested it using a simple Lambda function connected to Amazon DynamoDB.

During deployment, I found the following requirements and limitations:
  • The S3 bucket containing the deployment package must have versioning enabled. Lambda references a specific version of the  .zip  file rather than only using the object key. This ensures that the deployed package does not change when a new file is uploaded using the same key.
  • When creating or updating the function, you must provide the S3 object version and set the storage mode to  REFERENCE . The mode must be specified on every code update; otherwise, Lambda defaults to  COPY .
  • The S3 bucket policy must allow the Lambda service principal,  lambda.amazonaws.com , to perform  s3:GetObject  and  s3:GetObjectVersion .
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "LambdaSelfManagedCodeAccess",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": [
"arn:aws:s3:::my-bucket/my-function.zip"
],
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Condition": {
"ArnLike": {
"aws:SourceArn": "arn:aws:lambda:us-east-1:111122223333:function:my-function"
}
}
}
]
}
  • The built-in Lambda console code editor was not available for the function using  REFERENCE  mode.


Does  REFERENCE  mode affect Lambda performance?

To find out, I benchmarked two functionally identical Lambda functions that differed only in code storage mode.

Test setup

Configuration
 lambda-storagemode-copy 
 lambda-storagemode-reference 
Storage mode
 COPY  (default)
 REFERENCE  (self-managed S3)
Runtime
Python 3.14
Python 3.14
Architecture
 x86_64 
 x86_64 
Application code
Identical
Identical
Workload
DynamoDB  PutItem 
DynamoDB  PutItem 
Memory configurations tested
128 MB–3008 MB
128 MB–3008 MB
Both functions were profiled with  AWS Lambda Power Tuning  using the same parameters to keep the test conditions as consistent as possible.

Cold-start performance

To isolate cold-start behavior, every invocation was forced to launch a new execution environment.
Configuration: 15 invocations per memory size ·  onlyColdStarts: true  ·  parallelInvocation: false  ·  discardTopBottom: 0 
Memory
 COPY 
 REFERENCE 
128 MB
811.36 ms
807.31 ms
256 MB
764.52 ms
712.20 ms
512 MB
558.92 ms
644.49 ms
1024 MB
629.97 ms
549.06 ms
1536 MB
620.68 ms
681.16 ms
3008 MB
760.22 ms
605.82 ms
AWS Lambda Power Tuning selected 512 MB as the balanced configuration for both functions.
Neither mode was consistently faster across the tested memory sizes. With only 15 invocations per memory size, these results should be treated as directional .

Standard Power Tuning performance

Next, I ran Power Tuning with forced cold starts disabled and the default outlier trimming enabled.
Configuration: 15 invocations per memory size ·  onlyColdStarts: false  ·  parallelInvocation: true  ·  discardTopBottom: 0.2 
Memory
 COPY 
 REFERENCE 
128 MB
120.70 ms
35.53 ms
256 MB
15.55 ms
13.57 ms
512 MB
8.57 ms
8.46 ms
1024 MB
8.71 ms
8.11 ms
1536 MB
8.40 ms
8.32 ms
3008 MB
8.04 ms
11.75 ms
Both functions again converged on 512 MB as the balanced configuration. I did not use the 128 MB row for a mode-to-mode comparison. At that memory allocation, a small number of slower invocations can disproportionately affect the average.

Takeaway

Across both tests,  COPY  and  REFERENCE  showed no consistent runtime performance advantage over one another.

Sources



Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article