Search code examples
ruby-on-railsruby-on-rails-4herokubowerbuildpack

Heroku and slug size bloat


I'm starting to hit a wall with my Heroku app.

I'm well aware of the normal issues with slug size, re: images, PDFs, and other materials but my problem likely revolves around other assets brought in by bower or possibly build packs.

https://devcenter.heroku.com/articles/slug-compiler Heroku Slug Size After Multiple Deployments

My Heroku compliled slug looks like so:

$ du -h --max-depth=1

4.0K    ./.bower-tmp
30M ./tmp
24K ./features
236K    ./config
195M    ./public
4.0K    ./log
34M ./bin
792K    ./db
355M    ./vendor
8.0K    ./.heroku
22M ./app
64K ./lib
8.0K    ./.bundle
136K    ./.bower-registry
22M ./.bower-cache
24M ./node_modules
12K ./.profile.d

By far the largest is Vendor (355M), but my local vendor folder is in fact empty as is public (195M).

But on heroku it looks like:

40M vendor/ruby-2.0.0
21M vendor/node
32K vendor/heroku
12K vendor/assets
103M vendor/jvm
192M vendor/bundle

195M public/assets (bower bloat?)

Which I'm guessing is one of several build packs for bower and for PDF generation.

https://github.com/heroku/heroku-buildpack-nodejs
https://github.com/heroku/heroku-buildpack-ruby
https://github.com/razorfly/wkhtmltopdf-buildpack

My app itself looks lean-ish at 22M, but my current heroku SLUG is 298.4MB! and the vendor directory alone is more than that according to du, should I not be using these build packs and instead migrate to asset compilation on my local machine between builds? I'm not sure what a good deployment strategy (/ slug diet) should look like, any ideas would be greatly appreciated.

UPDATE:

I also tried rebuilding the slug from what I read had worked for others, but to no effect. Slug size after compilation remained the same.

heroku plugins:install https://github.com/heroku/heroku-repo.git
heroku repo:rebuild -a appname

GIST of build: https://gist.github.com/holden/b4721fc798bdaddf52c6

UPDATE 2 (after following the excellent idea presented by drorb)

12K ./.profile.d
21M ./app
4.0K    ./log
812K    ./db
8.0K    ./.heroku
236K    ./config
195M    ./public
19M ./.bower-cache
60K ./lib
253M    ./vendor
4.0K    ./.bower-tmp
128K    ./.bower-registry
34M ./bin
30M ./tmp
24M ./node_modules
24K ./features
8.0K    ./.bundle

Vendor

12K vendor/assets
193M    vendor/bundle
21M vendor/node
32K vendor/heroku
40M vendor/ruby-2.0.0

Public/Assets (very long)

https://gist.github.com/holden/ee67918c79dd3d197a6b


Solution

  • The size of vendor/jvm is 103M. Since you are not using JRuby the only reason I could find for having it is using the yui-compressor gem. Looking at the heroku-buildpack-ruby it seems that the JVM is installed in this case:

    def post_bundler
      if bundler.has_gem?('yui-compressor') && !ruby_version.jruby?
        install_jvm(true)
        ENV["PATH"] += ":bin"
      end
    end
    

    If you can avoid using yui-compressor you should be able to save 103M on your slug size.