Skip Navigation
Show nav
Heroku Dev Center
  • Get Started
  • Documentation
  • Changelog
  • Search
  • Get Started
    • Node.js
    • Ruby on Rails
    • Ruby
    • Python
    • Java
    • PHP
    • Go
    • Scala
    • Clojure
  • Documentation
  • Changelog
  • More
    Additional Resources
    • Home
    • Elements
    • Products
    • Pricing
    • Careers
    • Help
    • Status
    • Events
    • Podcasts
    • Compliance Center
    Heroku Blog

    Heroku Blog

    Find out what's new with Heroku on our blog.

    Visit Blog
  • Log inorSign up
View categories

Categories

  • Heroku Architecture
    • Dynos (app containers)
    • Stacks (operating system images)
    • Networking & DNS
    • Platform Policies
    • Platform Principles
  • Command Line
  • Deployment
    • Deploying with Git
    • Deploying with Docker
    • Deployment Integrations
  • Continuous Delivery
    • Continuous Integration
  • Language Support
    • Node.js
    • Ruby
      • Working with Bundler
      • Rails Support
    • Python
      • Background Jobs in Python
      • Working with Django
    • Java
      • Working with Maven
      • Java Database Operations
      • Java Advanced Topics
      • Working with Spring Boot
    • PHP
    • Go
      • Go Dependency Management
    • Scala
    • Clojure
  • Databases & Data Management
    • Heroku Postgres
      • Postgres Basics
      • Postgres Getting Started
      • Postgres Performance
      • Postgres Data Transfer & Preservation
      • Postgres Availability
      • Postgres Special Topics
    • Heroku Data For Redis
    • Apache Kafka on Heroku
    • Other Data Stores
  • Monitoring & Metrics
    • Logging
  • App Performance
  • Add-ons
    • All Add-ons
  • Collaboration
  • Security
    • App Security
    • Identities & Authentication
    • Compliance
  • Heroku Enterprise
    • Private Spaces
      • Infrastructure Networking
    • Enterprise Accounts
    • Enterprise Teams
    • Heroku Connect (Salesforce sync)
      • Heroku Connect Administration
      • Heroku Connect Reference
      • Heroku Connect Troubleshooting
    • Single Sign-on (SSO)
  • Patterns & Best Practices
  • Extending Heroku
    • Platform API
    • App Webhooks
    • Heroku Labs
    • Building Add-ons
      • Add-on Development Tasks
      • Add-on APIs
      • Add-on Guidelines & Requirements
    • Building CLI Plugins
    • Developing Buildpacks
    • Dev Center
  • Accounts & Billing
  • Troubleshooting & Support
  • Integrating with Salesforce
  • Language Support
  • Java
  • Java Advanced Topics
  • Warming Up a Java Process

Warming Up a Java Process

English — 日本語に切り替える

Last updated December 16, 2019

Table of Contents

  • Prebooting an application
  • Creating a warm-up script
  • Enabling the warm-up script
  • Customizing the warm-up script
  • Further reading

The first request made to a Java or JVM web application is often substantially slower than the average response time over the life of the process. This warm-up period can usually be attributed to lazy class loading and just-in-time compilation, which optimize the JVM for subsequent requests that execute identical code.

As a result, many users find it beneficial to submit a few artificial requests into the JVM process before using it to handle real traffic. Even a simple set of no-op requests to your application can warm-up the networking and messaging parts of the stack, which usually constitute a large portion of the request overhead.

This article describes one strategy for implementing such behavior on Heroku.

Prebooting an application

In order to do anything with a process before the router starts sending it requests, you must enable Heroku’s Preboot feature. This will provide some time between when the app starts up and when it begins handling real traffic.

Creating a warm-up script

With pre-boot enabled, you can create a script that will run alongside your application and send some requests before it’s brought into the pool of active dynos.

Add a bin/ directory in the root of your project, and create a bin/warmup file. Open that file in your favorite editor and add the following code:

until $(curl -o /dev/null -s -I -f http://localhost:$PORT); do
  sleep 5
done

This ensures that the script waits until the main process has started up and bound to $PORT before sending any requests.

To send the requests, add this code next:

for ROUTE in $WARMUP_ROUTES; do
  echo "[warmup] calling $ROUTE"
  curl -L "http://localhost:$PORT$ROUTE" >/dev/null 2>&1
done

This sends a single request to the routes defined by the $WARMUP_ROUTES config variable, which you can set like this:

$ heroku config:set WARMUP_ROUTES="/ /hello /db"

This will send warm-up requests to three different routes: /, /hello and /db. You will need to customize this variable to suit your application’s routes. Some users prefer to add special routes specifically for warm-up. It is not required to execute application specific logic, but it can help.

After you’ve chosen the routes, you need to add this script to your Procfile.

Enabling the warm-up script

To use the bin/warmup script, modify your existing Procfile command for the web process by adding the sh bin/warmup & prefix to it. For example, you might have:

web: sh bin/warmup & java -jar my-app.jar

This will start the warm-up script in the background, and the java process in the foreground.

Note that if you are running Windows locally, this script won’t work when you run heroku local because it’s specific to Linux platforms (like the one on Heroku). In this case, you’ll need to create a Procfile.windows and add it to the command by running heroku local -f Procfile.windows. The Windows Procfile will contain only the java command for the web: entry.

Once this is complete, add your changes to Git and redeploy:

$ git add bin/warmup Procfile
$ git commit -m "warmup"
$ git push heroku master

When your app restarts, it will behave as normal, but you’ll see a few [warmup] statements in the logs, which correspond to the routes you defined earlier.

You can find a complete example of an application that is set up this way in the sample app on Github.

Customizing the warm-up script

Because the bin/warmup script is written in Bash, it can be customized by writing a few lines of code.

For example, if you want to repeat the warm-up requests multiple times, you could add for loop around the curl command. For example:

for i in {1..10}; do
   curl ...
done

It is reasonable to repeat each warm-up request as much as a few hundred times, though not usually necessary.

If you’d like to make a more robust warm-up script, you can use a language other than Bash. Ruby and Python are both available on the Cedar stack, and you can even write a simple JVM app for this purpose.

Further reading

Advanced users may want to configure the JVM so that just-in-time compilation is better optimized for their application and thus improves warm-up time. A great resource for this is Java Performance: The Definitive Guide by Scott Oaks.

Please see the Dev Center for more information on Heroku’s Java Support.

Keep reading

  • Java Advanced Topics

Feedback

Log in to submit feedback.

Information & Support

  • Getting Started
  • Documentation
  • Changelog
  • Compliance Center
  • Training & Education
  • Blog
  • Podcasts
  • Support Channels
  • Status

Language Reference

  • Node.js
  • Ruby
  • Java
  • PHP
  • Python
  • Go
  • Scala
  • Clojure

Other Resources

  • Careers
  • Elements
  • Products
  • Pricing

Subscribe to our monthly newsletter

Your email address:

  • RSS
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku Blog
    • Heroku News Blog
    • Heroku Engineering Blog
  • Heroku Podcasts
  • Twitter
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku
    • Heroku Status
  • Facebook
  • Instagram
  • Github
  • LinkedIn
  • YouTube
Heroku is acompany

 © Salesforce.com

  • heroku.com
  • Terms of Service
  • Privacy
  • Cookies
  • Cookie Preferences