Optimizing Rails deployment on Heroku
Time-consuming deployment process makes developers wait longer to see their changes live. Apart from being a context switch trigger, it becomes a serious issue when landing an important fix on production takes minutes or more.
Jan Dudek
Unified Payroll is fully launched!
Read Story →Checklist: How to Evaluate a Potential Payroll Provider
Read Story →Pilot is now Plane!
Read Story →As our app had become more complex, its deployment time became a serious bottleneck for our continuous delivery. Here’s what we did to handle it.
What gets measured gets managed.
The first step to optimization is to measure what actually takes time.Initially, I thought we’d need a sophisticated profiler to collect metrics. Turns out a simple Ruby script backed by Google Sheets is well suited for the task.Luckily, Heroku provides descriptive logs from the deployment process and makes them available through the [Platform API](https://devcenter.heroku.com/articles/platform-api-reference). The official [Ruby gem](https://github.com/heroku/platform-api) is quite handy, too.The essential information can already be found in the build log, which makes it easy to analyse past data. The script we put together iterates over past deploys, fetches their build logs and extracts the following data with the help from several regular expressions: *Bundle time.** Have you ever noticed that Bundle completed (1.39s) message? That’s exactly what we’re using here. *Webpack compilation time.** Similarly, Webpack logs Time: 22518ms. *Assets precompilation time.** We still make use of Sprockets for stylesheets and images. *Database migrations,** run automatically after each deploy. Their completion time is also present in the log.npm install
doesn’t output processing time by default, but we solved this by adding appropriate scripts to our app’s package.json
:```json "scripts": { "preinstall": "echo \"$(date -u) Starting npm install\"", "postinstall": "echo \"$(date -u) Finished npm install\"" }```Lastly, we get the actual deployment start and finish timestamps from Heroku API. The difference between the things we’ve measured and the complete deploy duration is labeled as unknown time.And Google Sheets’ area chart works great with our measurements:![Deployment metrics](https://pilot-blog.s3.amazonaws.com/2016/Jun/Deployment_2x-1466437422596.png)👉 The script we’ve been using can be found [in this Gist](https://gist.github.com/jdudek/8fd3cbdc577684039b0eac4d506b8b03).