Laravel Vapor and the AWS Lambda 50MB Limit

I've been working with Laravel vapor over the last several years and one thing that comes up every now and then is hitting the 50MB AWS Lambda limit. As the Laravel Vapor documentation states:

AWS Lambda has strict limitations on the size of applications running within the environment. If your application exceeds this limit, you may take advantage of Vapor's Docker-based deployments. Docker-based deployments allow you to package and deploy applications up to 10GB in size.

If you've hit the 50MB limit you might be considering using a Docker runtime as a potential solution. While this is a perfectly valid option, it comes with its own set of complexities and as you'll see may not be necessary for your application.

#What about Reusable Vendors?

Indeed, Laravel Vapor introduced the concept of Reusable Vendors back in 2019 to help reduce the size of your deployment package by reusing common vendor dependencies.

However, that functionality never worked with the Amazon Linux 2 runtimes and now seems to have been officially deprecated. Given the depreciation of Reusable Vendors here are four alternatives that you can use to get your application size down:

#1. Configure your vapor.yml file to ignore unnecessary folders

The vapor.yml file allows you to specify folders to ignore during the deployment. This is handy for excluding folders that are not needed in your vapor environment. As an example, in my application I add the following folders to my ignore array:

1ignore:
2 - .github
3 - tests
4 - docker
5 - cypress
6 - bootstrap/ssr

#2. Running composer install --no-dev

By default, running composer install will include both the production and development dependencies. Appending the --no-dev flag will prevent Composer from installing the development dependencies thus reducing the size of your application bundle. In my app here's an example of the dependencies I keep in the require-dev section of my composer.json when using the --no-dev flag none of these dependencies are included in my vapor deployment.

1 "require-dev": {
2 "fakerphp/faker": "^1.19",
3 "hammerstone/airdrop": "^0.2.3",
4 "itsgoingd/clockwork": "^5.1",
5 "laravel/breeze": "^1.15",
6 "laravel/sail": "^1.15",
7 "laravel/tinker": "^2.7",
8 "laravel/vapor-cli": "^1.44",
9 "mockery/mockery": "^1.5",
10 "nunomaduro/collision": "^7.0",
11 "nunomaduro/larastan": "^2.6",
12 "orangehill/iseed": "dev-master",
13 "pestphp/pest": "^2.3",
14 "pestphp/pest-plugin-laravel": "^2.0",
15 "pestphp/pest-plugin-mock": "^2.0",
16 "phpmd/phpmd": "^2.12",
17 "sammyjo20/saloon-laravel": "^2.0",
18 "spatie/enum": "^3.13",
19 "spatie/laravel-ignition": "^2.0",
20 "spatie/laravel-typescript-transformer": "^2.1",
21 "tightenco/duster": "^0.6.0"
22},

#3. Remove the node_modules folder after compiling JavaScript.

If you're using a JavaScript build tool like Laravel Mix or Vite, it's likely that you'll have a node_modules directory in your project. This directory can be quite large and is not needed once your JavaScript has been compiled.

In my applications I remove the node_modules folder by adding the following to the build key of my vapor.yml file:

1build:
2 - 'rm -rf node_modules'

#4. Remove unused services from the aws/aws-sdk-php package

Recently a feature was merged into the official aws/aws-sdk-php package that allows you to remove unused services. Because this package is required by every Laravel Vapor application, this can have a significant impact on your bundle size. In my app removing unused services reduced my application deployment by over 30MB!

To set this up you'll need to first identify which services you are using by adding a key called aws/aws-sdk-php under the extra key in your composer.json file. Here's what I'm using in my app, but if you are using different AWS services you'll need to adjust accordingly:

1"extra": {
2 "aws/aws-sdk-php": [
3 "CloudWatch",
4 "CloudWatchLogs",
5 "Iam",
6 "Lambda",
7 "S3",
8 "Sqs",
9 "Ssm"
10 ]
11},

Then to actually remove any unused services add the following to your composer.json scripts object. This will run the new removeUnusedServices command as part of the composer dump-autoload lifecycle.

1"pre-autoload-dump": "Aws\\Script\\Composer\\Composer::removeUnusedServices",