Help!

Troubleshooting Judoscale: Handling Queue Time Spikes and Errors

But First!

Before diving in to any particular troubleshooting or debugging questions, please make sure you’re running the latest version(s) of the Judoscale gems for your app. Updating to the latest version has solved many issues for other users in the past!

Why Does My Queue Time Spike Whenever I Deploy My App?

Unless you’re using Heroku’s Preboot feature, your app will be temporarily unavailable while it boots, such as during deploys and daily restarts. During this time, requests are routed to your web dynos, where they wait. All this waiting is reflected in your request queue time, which will likely cause an autoscale for your app.

This is not a bad thing! Your app autoscaling during a deploy means it’ll quickly recover from the temporary downtime during boot, and of course, it’ll autoscale back down once it catches up.

If you want true zero-downtime deployment, you’ll need to use Preboot.

On platforms that don’t offer a preboot-style deployment (for example, Amazon ECS or Render), the same principle applies: new tasks need time to register with the load balancer before they can absorb traffic. If you’re seeing multiple upscales during each deploy, adjust your upscale frequency so we wait long enough to confirm the first upscale helped. You can also temporarily disable autoscaling with the Settings API at the start of a deploy and re-enable it once the new containers are healthy.

Why didn’t my scheduled scale apply while a Heroku deploy was running?

Heroku blocks formation changes on a Preboot app while a release phase or preboot cutover is still in progress. When this happens, the API returns Cannot change formation for a preboot app until release phase and preboot complete. If your Judoscale schedule tries to enforce a new min/max range during that window, Heroku will reject every attempt until the deploy finishes.

Judoscale automatically retries when we see that conflict, and we recently extended the retry window specifically to cover longer release phases. Even so, Heroku won’t allow the change until it has routed traffic to the new dynos, so the schedule may appear “stuck” at the previous limits until the deploy wraps up.

If you need the new range to apply immediately after deploys, keep an eye on how long your release phase runs and aim to keep it under a minute. For longer migrations, consider pausing autoscaling before the release, then re-enable it (or manually scale via heroku ps:scale) once Preboot reports healthy dynos. You can also re-save the schedule in the Judoscale dashboard after the release completes to trigger another enforcement pass.

If you routinely see that error outside of deploy windows, drop us a note with timestamps and we’ll investigate the Heroku API responses from our side.

Why is my queue time in Judoscale different from Scout or New Relic?

Request queue time is measured the same, but aggregated differently. Judoscale aggregates an average every 10 seconds, while other APM tools aggregate using buckets of a minute or more. This makes queue time in Judoscale a bit more “spikey”, but it also allows us to respond faster to a slowdown.

Why do I see API timeout errors from the Judoscale package in my logs?

The Judoscale adapter package reports metrics to our API every 10 seconds for every web and worker processes you’re running at a given time. For an application running 10 web containers with two processes on each container, this is over 170,000 requests in a day, not counting worker processes. This is a lot of API activity!

Our typical response time for the adapter API endpoint is around 5 milliseconds, but at our volume we do see occasional outliers taking several seconds. A few of those inevitably hit the 5-second timeout we specify in our adapters. This might cause an HTTP failure to be logged in your app’s logs, but it’s not a cause for concern. A tiny fraction of failed reports will not impact your autoscaling behavior at all.

Why do autoscale downsizes sometimes trigger Heroku H18 “Server Request Interrupted” errors?

H18 errors occur when the Heroku router closes a client connection before the dyno finishes responding. During a downscale, Heroku immediately sends a SIGTERM to the dyno we’re removing and there’s no connection-draining step, so any in-flight or keep-alive requests on that dyno can be interrupted. This isn’t unique to Judoscale—we use the same autoscaling mechanism as Heroku’s own native autoscaler, so unfortunately there’s not much we can do.

If you see sporadic H18s during downscales, that’s expected platform behavior rather than a misconfiguration. Monitor the rate, but plan for the occasional interrupted request whenever Heroku removes web dynos under load.

In practice, H18s are rare. Even on our own app that handles roughly 3,000 requests per second, we only see about 20 H18s per day (roughly one in 10 million requests). That trade-off is generally acceptable compared to the efficiency gains from autoscaling.