Once a slug size reaches 300 MB, Heroku will warn about larger slug sizes having the potential to cause longer boot times. The best practice is to keep slug sizes as small as possible for fast deploys and other operations.
Warning: You slug size (400 MB) exceeds our soft limit (300 MB) which may affect boot time
What is a slug
Slugs are compressed and pre-packaged copies of your application optimized for distribution to the dyno manager. When you git push to Heroku, your code is received by the slug compiler which transforms your repository into a slug. Scaling an application then downloads and expands the slug to a dyno for execution.
The steps that heroku takes once you push some code to git are:
- Checkout HEAD from the
master
branch. - Remove all files specified in
.slugignore
. - Download, build and install local dependencies as specified in your build file (for example, Gemfile, package.json, requirements.txt, pom.xml, etc.) with the dependency management tool supported by the language (e.g. Bundler, npm, pip, Maven).
- Package the filesystem as a slug archive.
Reducing Slug Size
There are a few steps that can be followed to reduce the slug size.
Purge build cache
Buildpacks cache some content to speed up future builds. But sometimes, when your dependencies change (especially when you remove a dependency), it might not be removed from the cache. So if you are facing unexpectedly high slug sizes and you have removed some dependencies from your project, try this first (if you can live with a slow build on the next deploy).
$ heroku plugins:install heroku-repo
$ heroku repo:purge_cache -a appname
Ignore files with .slugignore
Your .sligignore
should list directories and files that are in the repo (not ignored by .gitignore
) but not needed for the app to run on prod. Some examples of files like these are the tests, documentation and design files. To remove these from the slug, create a .slugignore
at the root of the project.
*.psd
/doc
/test
To check out what files are being put into the slug, you can also enter the heroku bash and check the filesystem.
heroku run bash -a appname
du -sh .[^.]* * | sort -hr
Node modules
This part is specific to apps that include an asset pipeline that bundles all JavaScript code to single script. If you are using a node server, this might not apply to you.
If you are using Rails with webpacker, you might have a lot of dependencies in node_modules
. But after the asset pipeline compiles the resources, you probably don’t need the node_modules
directory (unless you run custom node scripts at runtime that use those modules). To remove the node_modules
directory in this case, we can use the heroku-buildpack-post-build-clean
buildpack with a .slug-post-clean
file. The format of this file is the same as .gitignore
or .sligignore
, so just list out directories that you want to ignore from the final slug and they will be removed. One thing to make sure with the buildpack is that this should be the last one in the order otherwise it will remove the files before your actual buildpack runs.
But what if you are using custom node scripts that access the node_modules
at runtime? In that case, what we do is move those scripts to a separate directory with it’s own package.json
file. To install the dependencies into that directory along with the installation of root package.json
, add a postinstall
script to your root package.json
. This will instruct yarn to change directory to your custom script and install dependencies there after the dependencies of your root project are installed.
"scripts": {
"postinstall": "yarn --cwd lib/custom-node-script"
}
With this, you can then safely remove your root node_modules
directory even when using custom node scripts in a production Rails app.