I am trying to understand the deployment size limits for AWS Lambda as I encountered the following error after adding another layer to my Lambda function:
An error occurred: <function name> - Function code combined with layers exceeds the maximum allowed size of 262144000 bytes. The actual size is 269081659 bytes. (Service: AWSLambdaInternal; Status Code: 400; Error Code: InvalidParameterValueException; Request ID: <request ID>; Proxy: null).
I understand that the total uncompressed size of code + layers cannot exceed 250 MiB but I cannot understand how my code and layers have breached that limit. I especially cannot make my layers add up to the 'actual size' stated in the error.
I am using the Java 8 runtime and my jar is 54 MiB. Unzipped it is 140 MiB. I had two existing layers with the following sizes:
| Layer | Compressed size | Uncompressed size |
|---|---|---|
| Elasticsearch (jar) | 22 MiB | 54 MiB |
| ImageMagick | 17 MiB | 58 MiB |
I added a further layer, Ghostscript, which is 16 MiB compressed and 34 MiB uncompressed. Adding this layer resulted in the error from above.
My confusion arises because I can't make any combination of the compressed/uncompressed files match the error message. Reviewing the output of aws lambda get-function shows the uncompressed sizes for the code and layers.
Additionally I deployed each of my layers individually and ran df -h in the Lambda instance to see how much space was being used. Layers are loaded to /opt and the size of this mount point was more or less equal to the uncompressed size for Elasticsearch and ImageMagick (within a megabyte or two, and possibly only different due to using MB and MiB inconsistently). However df reported that /opt was 52 MB when the Ghostscript layer was added which is almost twice as large as the uncompressed size on my machine. Even with these numbers I cannot find a combination that gives the the 'actual size' listed in the error.
How can I find out the actual space taken up by my code and layers?
Notes on calculating compressed and uncompressed size:
- For jar files I took the size of the jar file itself as the compressed size. For the uncompressed size I used the
unzipcommand and used the size of the folder. - For the layers I used the size of the zip file downloaded from the AWS console (which matched the output from the
aws lambda get-functioncommand) as the compressed size. For the uncompressed size I extracted the zip file and used the size of the folder.