Skip to main content

Passenger Spinning down in Production

Servers • Asked by shakycode

My favorite combination of Rails/HTTP is Nginx + Passenger. They work wonderfully together and it's been super easy to setup across all of my apps. One thing I've noticed in some of my apps that don't see a lot of traffic is that after an unspecified period of time, Passenger will spindown and drop the database pool connection when the site is idle. Most won't experience this with an active app but I have a few apps and demo sites that don't receive much use and this happens frequently. This results in the next user visiting your site having to wait 1-3 seconds while Passenger spins up and your Rails ENV loads.

I've read the Passenger documentation and there's an option to pre-start the virtual host, but I'm not sure how that would affect restarts and deployment.

So to combat the issue, I've come up with a simple method to keep your app spun up 24/7.

You'll want to edit your crontab as whatever deploy user you have setup (in my environments, it's just deploy).

crontab -e
*/5 * * * * wget -O /dev/null -o /dev/null yoursite.com

What this does is a wget to your site's root url simulating a user visit and outputs the response to /dev/null (nowhere). In Cron we set it at to a 5-minute interval to keep the app up and running. Of course you'll need to have wget installed on your server which is simple enough via apt or yum.

This works well for me in my production environments and is a quick and dirty fix. If anyone else has another way of doing this without having to use a cron job, please let me know.

Cheers!


Good tip! This is especially useful for those people who are running a Heroku app on the free tier that gets hung for quite a while if you're not using it.

Only other thing I could think of is setting up something like Pingdom or a similar app that would make the HTTP requests for you. They'd give you the side benefit of alerting you if things go down.


Definitely useful for Heroku since they spin down when not in use. But this happens with Passenger quite a bit if your app is idle. It will spin down the environment which leads to a 1-4 second spinup time when the next GET request is made. The cron job takes care of that for you and keeps things nice and responsive.

I think Pingdom is a good idea since it can make a get request and notify you of the site being up/down. Although depending on their timeout interval, you may receive a down alert if your app is spun down and Pingdom tries to hit it and it takes a while to spin up.

I use Nagios for alerting and system checks (including HTTP/HTTPS) so maybe what I'm doing with the cron job is redundant, but it's definitely worked for me so far.

Now, to figure out why Passenger spins down and how to prevent it from doing that. What I do with the cron job is "hackish" in a way, so I'd like to really get Passenger to never spin down. I know there's a pre-start directive you can give to it in the virtualhost block, but I haven't played with it yet. Lazy fix, FTW. :)


I wonder how long it takes for Passenger to sleep an app. I haven't noticed it with things like Feedforward.io that I run but rarely use. Maybe there is other traffic to it that I didn't realize or something.

You might be able to set passenger_pool_idle_time to 0 and see if that disables the idle time. https://www.phusionpassenger.com/documentation/Users%20guide%20Nginx.html#PassengerPoolIdleTime


Sweet! This may be just what I need. I think I'm going to give it a shot. You're the man!

I should really start to do research once I actually wake up :)


Btw, in that link you sent it tells you what the default idle time is. This option may only occur once, in the http configuration block. The default value is 300. So it looks like 300 seconds of idle time to spin down. That would explain things easily on a low traffic application.


Login or Create An Account to join the conversation.

Subscribe to the newsletter

Join 27,623+ developers who get early access to new screencasts, articles, guides, updates, and more.

    By clicking this button, you agree to the GoRails Terms of Service and Privacy Policy.

    More of a social being? We're also on Twitter and YouTube.