mod_rails is on the way
Posted by David March 26, 2008 @ 10:26 PM
Hongli and crew from Phusion have been hard at work for some time to fix the ease-of-deployment issue on Apache with their Passenger project. They now have a video that demos how simple it’ll be to install and get running with mod_rails. Check it out.
Update: Hongli has posted some promising performance benchmarks for mod_rails.

Cool. Can it be used for other Ruby-frameworks also, or is it Rails-specific?
Hi Tuxie.
There is the following saying: jack of all traits, master of none. At the moment, our goal is to make Passenger a great deployment system for Ruby on Rails, one that is matched by none in terms of ease of use and low maintenance overhead.
This is the reason why other frameworks such as Camping and Merb are not supported at the moment. However, members from the community have expressed interest for support for other frameworks, so we’re definitely keeping the option open. And of course, because Passenger will be open source, interested parties may contribute support for other frameworks themselves.
- Hongli
That certainly looks impressive for ease of deployment. A few quick questions
Any word on how it is in terms of performance? Primarily in comparison to using Apache w/ mod-proxy to mongrel_cluster
In the video I didn’t see a way to specify which environment (i.e. production vs. development)?
Extremely exciting stuff—looks awesome!
Very good to see. Curious about the passenger-spawn-server… is it running Rails on a few separate processes, somewhat like Mongrel would, but making it a lot simpler to configure?
Btw, the video was a bit glitchy for me, in “FlowPlayer” the sound was cutting out, and the download (US1) had green flickering. Running Leopard here, with Quicktime+Flip4Mac but no divX, etc.
How about adapting it to use with Rack… that way many frameworks could be supported at once.
I don’t understand what would make creating a solid mod_ruby implementation harder than mod_rails? The specificity of an apache module to run a particular framework as opposed to a module to provide better performance to a particular scripting language seems odd.
If you can build a system that simply makes deploying Ruby on Apache easier it should be most of the work to make deploying Rails on Apache easier, or Merb, or Camping or anything written in Ruby. Why focus on supporting just this framework instead of the language as a whole, the solution just seems to approach the problem from the wrong direction.
Hi Eldon: According to our benchmarks, performance is slightly higher than mod_proxy->mongrel_cluster. Though overall performance is very similar because most of the time is spent in Rails. And yes, it’s possible to set RAILS_ENV. It defaults to “production” but you can configure it with a config option (described in the manual).
Nathan: Yes it runs separate processes. But it makes heavily use of fork() and copy-on-write semantics in order to reduce startup time and memory usage. For the latter you’d have to use our modified Ruby though. More details will be released soon.
The high quality video is encoded in H.264 with MP3 sound. We’ve tested it on MacOS X Leopard (VLC, mplayer, QuickTime) and Linux (mplayer).
Edoardo, James: See my first reply. Rack is an abstracting layer around framework-specific dispatchers, but Passenger does a lot more than just that so we can’t implement support for that in 10 minutes. For example, we do: - Automatic detection of virtual hosts that contain Rails apps. Heuristics for this is framework-dependent. A mod_ruby certainly wouldn’t be able to do this and will force you to write a few config options. - Preloading of framework code and application code for reduced startup time and reduced memory usage. The exact preloading method depends on the framework. mod_ruby wouldn’t be able to do this automatically either, it’ll force you to manually specify the dependencies to preload, just like mod_perl would.
See also http://izumi.plan99.net/blog/index.php/2008/03/27/passenger-and-other-ruby-frameworks/ for a detailed explanation.
This is really exciting news.
Is the only reason it’s mod_rails (instead of mod_ruby) because you have some automatic detection that would otherwise “force you to write a few config options”? If that is the case, I would say go the config file route. Not only to open it up for other frameworks, but it will open it up for other configurations.
If there is another, more technical reason, then just disregard my statement all together. :)
Andrew: That is one of the reason. The other one is simply schedule: our goal for 1.0 is to make a great Rails deployment system, and nothing more than that. Supporting other frameworks would deviate us from this goal and would increase development time. Nothing prevents Passenger from supporting other frameworks in the future.
The config file route isn’t really nice. People shouldn’t have to write configs. Please read my blog for detailed explanations.
Hongli: Thanks for the explanation. The lack of config file usage is definitely understandable. Especially if the automatic stuff you’re doing would require anything more than a basic config file. That would probably hurt the adoption rate and I know you don’t want that.
Again, thanks for the work and I am really looking forward to mod_rails.
I’m on my way to your blog for the details…
Looking forward to 1.0 – thanks for taking this on.
I must say that the sign language on the screen cast was quite distracting and annoying :(
“For the latter you’d have to use our modified Ruby though.”
Do you think the requirement of a “modified Ruby” will limit acceptance?
Hi Brian.
The modified Ruby is not a requirement. It’s an optional additional which will allow an additional 33% reduction of memory in your Rails app. Passenger will work fine with normal Ruby.
Does mod_rails do anything to aid in the posting of large blobs of data? Or is the Rails process still locked on actions such as a large upload?
Hi Mr. Khan,
Short answer: yes. ;)
Long answer: Passenger manages rails processes automatically and the number of the processes spawned depends on the current site traffic.
This means that if and when Passenger infers that a process is locked on an action such as a large upload, it will be able to determine for itself whether or not it is desirable to spawn other processes to handle (more) requests, based on the current site traffic.
We’ve built this product for stability and performance, and what we’ve shown you guys so far is only the tip of the iceberg. We’ll try to reveal more as we go :-).
Hope that answers your question.
- Ninh (The other half/crew of Phusion ;-))
if it proofes its performance in real life applications this mod definitively rocks. very straigt forward and so easy to use.
btw. the video is a pain to watch :-P anoying “green hand animation” and very distorted sound. anyway.. :)
Amazing. You’ve made me want to come back to RoR. Thanks!
Hi ilumine,
From the beginning, performance of real life applications was something we didn’t want to make too many concessions on for ease of use and we’ve taken a lot of preparations to try to ensure this.
For one, we’re currently working with some of the largest ruby on rails hosts as well as some of the largest Ruby on Rails powered websites this planet knows of to be able to determine this.
For now, suffice it to say that we’re going the extra mile on trying to ensure that Passenger is also capable of handling its own in heavy duty production environments, while maintaining ease of use.
Even though we’ve been able to infer that this is indeed the case through extensive simulations/tests, we’re really eager on hearing how it performs in a real life scenario and we’re awaiting the test results to inform you guys about this in more detail.
Regarding the screencast, due to time constraints on obtaining a preview/announcement slot at Railsconf, we had to rush the video a bit (in one go actually). Our apologies for this, and needless to say, we’ll get on it as soon as we’re done preparing passenger for release. Till then, we hope you guys will be able to sit through the agony of the almighty evil green hand ;)
Hi ilumine,
From the beginning, performance of real life applications was something we didn’t want to make too many concessions on for ease of use and we’ve taken a lot of preparations to try to ensure this.
For one, we’re currently working with some of the largest ruby on rails hosts as well as some of the largest Ruby on Rails powered websites this planet knows of to be able to determine this.
For now, suffice it to say that we’re going the extra mile on trying to ensure that Passenger is also capable of handling its own in heavy duty production environments, while maintaining ease of use.
Even though we’ve been able to infer that this is indeed the case through extensive simulations/tests, we’re really eager on hearing how it performs in a real life scenario and we’re awaiting the test results to inform you guys about this in more detail.
Regarding the screencast, due to time constraints on obtaining a preview/announcement slot at Railsconf, we had to rush the video a bit (in one go actually). Our apologies for this, and needless to say, we’ll get on it as soon as we’re done preparing passenger for release. Till then, we hope you guys will be able to sit through the agony of the almighty evil green hand ;)
Great work!
I’m somewhat sad to see all of this work done around Rails, instead of Rack, though.
I would rather have something built around Rack, with a magic ‘Rails’ setting available to do the Rails-specific magic.
All of the latest Ruby web servers & frameworks are all built around Rack so we can all work together easily.
It no longer has to matter if an app is Rails or Merb or Camping or a custom Rack app, etc … everything plays together nicely!
I can’t wait to dig into the code and see how this was done and if it might be easy to have a ‘mod_rack’ instead.
Great, great work!
And what about Rails code changing? I am afraid, you have to restart Apache every time you change something in the code (Ruby does not work like PHP where all resources are deleted and removed every request). I see the problem with all other projects and application served by such Apache server (including mod_php). They all will we be dead when somebody try to refresh one Rails project. Does it mean you have to reserve one Apache per one Rails project? It seems to be stupid.
Another problem I see is huge memory usage. Every fork has to contain Ruby interpreter and all Rails’ staff. It might be a huge waste of RAM. And even worse, every fork has to contain all mod_* modules even if it is used only for static data parsing. This is another argument against using mod_* at all. With FastCGI or proxy balancer -> ebb/thin/emongrel clusters I can save a lot of memory. And I can isolate projects. If one dies, others won’t be even touched. When one mod_* dies, there is a risk that the all die because mod_* are internal part of Apache server.
This looks very promising and just made my day.
Hi Jaroslaw,
Changing code is not an issue for Passenger, since it is able to restart individual applications without restarting Apache. The only thing you’ll have to be afraid of is that you don’t have to restart at all ;-).
Moreover, I want to point out that one should never ‘just change code’ in a live production environment. There is a reason why Rails has a development environment you know ;)
Passenger has also been designed to be robust, and with robust, we mean robust in the ‘formal method’ sense of the word, i.e. all operations of the application are well defined, and from this it is guaranteed that the application will not get into a state that is not defined. (And just to be sure, we’ve tested this intensively with automated unit tests, integration tests, stress tests and benchmarks).
In other words, Passenger should not behave unexpectedly, and we’ve put a lot of effort into making it self-sustainable.
That said, we’ve also tackled the issue of efficiency with a pooling algorithm that will be described in more detail in our developer documentation.
More importantly however is to point out that a fork does NOT have to entail all the things that you’re stating and for more on this, I kindly refer you to read up on ‘copy on write’, an operating systems design concept that’s explained in detail by many computer science literature, such as ‘Operating System Concepts’ by Silberschatz et al (http://codex.cs.yale.edu/avi/os-book/os7/). In particular, http://codex.cs.yale.edu/avi/os-book/os7/slide-dir/ch9.pdf (slide 18) would offer good reading material. In short: forked Apache processes use very little additional memory (along the lines of several kilobytes), and not double the memory as you seem to think..
A concise explanation for this would be to say that when two objects a and b are indistinguishable at the beginning of their life cycle, they point to the same object (not two different objects). Only when operations are being performed on a and/or b that cause side effects, then and only then will the object be copied. Since side effects are the result of state changes (resulting from write actions) this technique is called copy-on-write. Needless to say, this results in a significant improvement of memory use (but also comes at the cost of more time complexity, but we’ve taken good care of this :-)).
We’ve applied this optimization to the garbage collector of MRI, and will release this Ruby branch with Passenger. The use of this Ruby branch however is not mandatory, but optional.
Hope this post has answered your questions. :-)
Hi Jaroslaw,
Changing code is not an issue for Passenger, since it is able to restart individual applications without restarting Apache. The only thing you’ll have to be afraid of is that you don’t have to restart at all ;-).
Moreover, I want to point out that one should never ‘just change code’ in a live production environment. There is a reason why Rails has a development environment you know ;)
Passenger has also been designed to be robust, and with robust, we mean robust in the ‘formal method’ sense of the word, i.e. all operations of the application are well defined, and from this it is guaranteed that the application will not get into a state that is not defined. (And just to be sure, we’ve tested this intensively with automated unit tests, integration tests, stress tests and benchmarks).
In other words, Passenger should not behave unexpectedly, and we’ve put a lot of effort into making it self-sustainable.
That said, we’ve also tackled the issue of efficiency with a pooling algorithm that will be described in more detail in our developer documentation.
More importantly however is to point out that a fork does NOT have to entail all the things that you’re stating and for more on this, I kindly refer you to read up on ‘copy on write’, an operating systems design concept that’s explained in detail by many computer science literature, such as ‘Operating System Concepts’ by Silberschatz et al (http://codex.cs.yale.edu/avi/os-book/os7/). In particular, http://codex.cs.yale.edu/avi/os-book/os7/slide-dir/ch9.pdf (slide 18) would offer good reading material. In short: forked Apache processes use very little additional memory (along the lines of several kilobytes), and not double the memory as you seem to think..
A concise explanation for this would be to say that when two objects a and b are indistinguishable at the beginning of their life cycle, they point to the same object (not two different objects). Only when operations are being performed on a and/or b that cause side effects, then and only then will the object be copied. Since side effects are the result of state changes (resulting from write actions) this technique is called copy-on-write. Needless to say, this results in a significant improvement of memory use (but also comes at the cost of more time complexity, but we’ve taken good care of this :-)).
We’ve applied this optimization to the garbage collector of MRI, and will release this Ruby branch with Passenger. The use of this Ruby branch however is not mandatory, but optional.
Hope this post has answered your questions. :-)
Hi Jaroslaw,
Changing code is not an issue for Passenger, since it is able to restart individual applications without restarting Apache. The only thing you’ll have to be afraid of is that you don’t have to restart at all ;-).
Moreover, I want to point out that one should never ‘just change code’ in a live production environment. There is a reason why Rails has a development environment you know ;)
Passenger has also been designed to be robust, and with robust, we mean robust in the ‘formal method’ sense of the word, i.e. all operations of the application are well defined, and from this it is guaranteed that the application will not get into a state that is not defined. (And just to be sure, we’ve tested this intensively with automated unit tests, integration tests, stress tests and benchmarks).
In other words, Passenger should not behave unexpectedly, and we’ve put a lot of effort into making it self-sustainable.
That said, we’ve also tackled the issue of efficiency with a pooling algorithm that will be described in more detail in our developer documentation.
More importantly however is to point out that a fork does NOT have to entail all the things that you’re stating and for more on this, I kindly refer you to read up on ‘copy on write’, an operating systems design concept that’s explained in detail by many computer science literature, such as ‘Operating System Concepts’ by Silberschatz et al (codex.cs.yale.edu/avi/os-book/os7/). In particular, codex.cs.yale.edu/avi/os-book/os7/slide-dir/ch9.pdf (slide 18) would offer good reading material. In short: forked Apache processes use very little additional memory (along the lines of several kilobytes), and not double the memory as you seem to think..
A concise explanation for this would be to say that when two objects a and b are indistinguishable at the beginning of their life cycle, they point to the same object (not two different objects). Only when operations are being performed on a and/or b that cause side effects, then and only then will the object be copied. Since side effects are the result of state changes (resulting from write actions) this technique is called copy-on-write. Needless to say, this results in a significant improvement of memory use (but also comes at the cost of more time complexity, but we’ve taken good care of this :-)).
We’ve applied this optimization to the garbage collector of MRI, and will release this Ruby branch with Passenger. The use of this Ruby branch however is not mandatory, but optional.
Hope this post has answered your questions. :-)
Does anyone else think the voice over sounded like something out of Speed Racer?
I’ll just say thanks for doing this. This will create tens of millions of $ in value and accelerate RoR and Ruby. Bravo.
As for sign language being annoying, try being deaf. We had it in a lot of classes at RIT and I think its great. Thanks for being so thoughtful.
Isn’t Litespeed doing all this and more already?
Litespeed is doing that in a way, but Litespeed is closed-source and commercial.
I don’t know enough about Litespeed to comment too intelligently on it, but one could make the argument that much of open source is reimplementing closed-source things. Often times, that open source implementation becomes better than the closed source item it was meant to replace because of all the eyes on the code.
I think we can expect the same to happen with mod_rails/passenger. It’s definitely been something the Rails community has a lot of desire for.
LiteSpeed ruby-lsapi is open source as well, under BSD/Ruby style license.
http://www.litespeedtech.com/ruby-lsapi-module.html
I would like to see a benchmark comparison between mod_rails and LiteSpeed.