Preloading Rails applications in production

When it’s time to take your application online, there are several decisions to make. Today I would like to talk about application preloading and explain why I prefer preloading applications in production.

But first things first. What’s is preloading anyway?

Preloading the application is a process of loading up all application files and dependencies to virtual memory. If it would be a game, this might be a difference between loading just first two levels of the game versus loading the game as a whole. What’s not loaded at first will be loaded later from the disk when required.

The opposite of preloading is lazy loading. Lazy loading saves us some memory at first and as a side product makes the boot process faster which might be a decent optimization for large applications.

But if you can, you should probably preload your application.

My main argument is predictability. After you preload your application, it’s up and served entirely from virtual memory. That means you won’t have to load anything from the disk at random. You also know that changes to the underlying files won’t change the application (until you need to start it again, that is).

To me this is easy to grasp.

But that’s not the whole story just yet. With multi-process application servers like Puma, we have to pay attention to preloading in terms of forking strategies. Preloading is helpful for sharing workers’ memory and forking new worker faster. But on the other hand, it’s not always possible. In Puma, preloading and phased restarts are not compatible.

Since preloading is now default in Puma 5, you opt-out of it with:

preload_app! false

If you don’t know what a phased restart is, I wrote before about graceful restarts in Puma.

So if you are in this situation, you need to think twice if you need phased restarts or keep things simple with preloading. It’s also worth noting that you might need the directory option to change directories when updating so that you don’t break your running application.

Personally, I like to keep things simple. I might depend on regular restarts and preloading while offloading the gracefulness garantees to systemd socket activation. I can copy new files over and restart.

Whatever you do, know what you are doing!


I wrote a complete guide on web application deployment. Ruby with Puma, Python with Gunicorn, NGINX, PostgreSQL, Redis, networking, processes, systemd, backups, and all your usual suspects.

More →