Forum: Ruby on Rails Ruby on Rails performance

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
E4a3f5e1837b1ec5efe0feecf9725323?d=identicon&s=25 Arnold Soginet (delphirocks)
on 2005-11-29 07:40
Hi,

I'm just starting to play around with ruby and rails. I love the MVC
concept, and the language itself is a lot of fun also.

There is one thing that's really bugging me - every rails site I've seen
so far (with the exception of this forum) seems to render very slowly.
There is this longer than normal (compared to PHP, ASP.net, JSP) delay
before the site gets loaded.

Is this the price to pay for using the framework?
Can anyone point me to a fastloading rails page?

thx
B1102f65359ee629df508c7857f03b1c?d=identicon&s=25 sitharus (Guest)
on 2005-11-29 08:43
(Received via mailing list)
On 29/11/2005, at 7:40 PM, arnold soginet wrote:

> Can anyone point me to a fastloading rails page?
It really depends on the site, for example my site at http://
wishlists.sitharus.com/ produces pages in 0.5-2 seconds depending on
the number of items and that's with a slow machine. Don't forget that
Rails is a fairly young framework, I'm sure that in time the speed
will improve.

Personally I find the ease of development a real bonus, hardware is
cheaper than my time ;)
38a8230ed3d5c685558b4f0aad3fc74b?d=identicon&s=25 joevandyk (Guest)
on 2005-11-29 08:56
(Received via mailing list)
http://tadalist.com works for me.
Af95bdaf87958c40150b813e94381bfd?d=identicon&s=25 Christer Nilsson (christer)
on 2005-11-29 08:59
Matz is working on the Ruby Virtual Machine. It's not Rails slowing
things down, it's Ruby.

Christer
8cb2fab8fddc8626073f40f0106c0077?d=identicon&s=25 hosiawak (Guest)
on 2005-11-29 09:04
(Received via mailing list)
On 11/29/05, arnold soginet <angerer@yahoo.com> wrote:
>
> Hi,
>
>
> Can anyone point me to a fastloading rails page?
>
> thx
>
> --
>

http://nitrozen.com loads pretty fast :)

It depends on how the application is written, not only what
language/framework is used.
The production hardware is of great importance, libraries
In reality you can get <1second /request rendering easily.

Here's how to optimize Rails usage:

http://weblog.textdrive.com/article/175/rails-opti...
E555e7c34196967444a47a96395a23ab?d=identicon&s=25 skaes (Guest)
on 2005-11-29 09:12
(Received via mailing list)
Christer Nilsson wrote:

>Matz is working on the Ruby Virtual Machine. It's not Rails slowing
>things down, it's Ruby.
>
>Christer
>
>
>
Ruby performance could certainly be improved. But this is, although
important, only a tiny piece of the puzzle. Rails can also be slowing
things down, if not used in a way that enables good performance.

I blog about Rails performance on http://railsexpress.de/blog

-- stefan
E555e7c34196967444a47a96395a23ab?d=identicon&s=25 skaes (Guest)
on 2005-11-29 09:24
(Received via mailing list)
Karol Hosiawa wrote:

>>--
>>
>>
>>
>
>http://nitrozen.com loads pretty fast :)
>
>It depends on how the application is written, not only what
>language/framework is used.
>
>
Very true.

>The production hardware is of great importance, libraries
>
>
In a shared hosting environment, it's hard to achieve good performance.

>In reality you can get <1second /request rendering easily.
>
>
Just below 1 sec per request is very slow. My own app runs at about 10
ms per request.

>Here's how to optimize Rails usage:
>
>http://weblog.textdrive.com/article/175/rails-opti...
>
>
>
Subscribe to my blog, too. I post Rails performance related issues on a
regular basis there.

http://railsexpress.de/blog

-- stefan
132a94ca65959bda6c74fae54bff2425?d=identicon&s=25 ezra (Guest)
on 2005-11-29 09:24
(Received via mailing list)
On Nov 28, 2005, at 10:59 PM, Phillip Hutchings wrote:

>> There is this longer than normal (compared to PHP, ASP.net, JSP)
> speed will improve.
>
> Personally I find the ease of development a real bonus, hardware is
> cheaper than my time ;)


Rails can be plenty fast when used correctly. One site I built is
very data heavy and it loads plenty fast compared to other sites of
its size. Check it out http://yakimaherald.com

Cheers-
-Ezra Zygmuntowicz
WebMaster
Yakima Herald-Republic Newspaper
ezra@yakima-herald.com
509-577-7732
82476266af9d460415d8f1fc16bb54ed?d=identicon&s=25 Jarkko Laine (jarkko)
on 2005-11-29 10:04
(Received via mailing list)
On 29.11.2005, at 8.40, arnold soginet wrote:

> Hi,
>
> I'm just starting to play around with ruby and rails. I love the MVC
> concept, and the language itself is a lot of fun also.
>
> There is one thing that's really bugging me - every rails site I've
> seen
> so far (with the exception of this forum) seems to render very slowly.

Could you give some examples?

> There is this longer than normal (compared to PHP, ASP.net, JSP) delay
> before the site gets loaded.
>
> Is this the price to pay for using the framework?
> Can anyone point me to a fastloading rails page?

Besides what's come up already:
* http://www.43things.com/
* http://odeo.com/
* http://www.aaltonenshoe.com/ (Running off a shared Textdrive
service and plenty fast even across the Atlantic)
* Every modern typo blog since typo uses caching pretty heavily.

//jarkko
165b8bf9238f9fc39a80a709f1b5510a?d=identicon&s=25 allen (Guest)
on 2005-11-29 18:39
(Received via mailing list)
Keep in mind that rails in development will reload its components
everytime to compensate for changes you are making in the development
cycle. Once you move into a production mode, you will notice better
speeds.

Also, I have been impressed how snapier Rails is once deploying under a
FastCGI-enabled web server!

Speed of the application is dependent more in Rails and Ruby. Look into
optimizing your web service, database access, server tuning, and network
latencies. Of course, you would do those things anyway.

Allen
E4a3f5e1837b1ec5efe0feecf9725323?d=identicon&s=25 Arnold Soginet (delphirocks)
on 2005-11-29 21:38
> Also, I have been impressed how snapier Rails is once deploying under a
> FastCGI-enabled web server!

I'll definitely check it out, once I've got a little more ruby under my
belt.

> Speed of the application is dependent more in Rails and Ruby. Look into
> optimizing your web service, database access, server tuning, and network
> latencies. Of course, you would do those things anyway.

I agree.

It's good to see that some of those sites (especially Stefan's recipes)
do load pretty fast...

Thanks guys.
D36eff3004b39abc4b93fe8a410d8bd3?d=identicon&s=25 rm_rails (Guest)
on 2005-11-30 07:55
(Received via mailing list)
Stefan Kaes wrote:
> Ruby performance could certainly be improved. But this is, although
> important, only a tiny piece of the puzzle. Rails can also be slowing
> things down, if not used in a way that enables good performance.

One thing I know you can do with Java/JSP and ASP.NET is to use
JspWriter.flush() or Page.Response.Flush()/HtmlTextWriter.Flush()
to send parts of a page to a browser while still computing the
remainder of the page.  The browser will happily render the
HTML as it receives it.  Assuming the header is quick
to generate) a user gets instant feedback.   And for a long
page, everything "above the fold" may be generated and rendered
almost instantly even if it takes seconds to generate the rest
of the HTML page that's not visible until scrolling down - and
by the time the user does scroll down it'll be ready for him.

I'm too new to know how to do this in rails, though.
E555e7c34196967444a47a96395a23ab?d=identicon&s=25 skaes (Guest)
on 2005-11-30 09:04
(Received via mailing list)
Ron M wrote:

> remainder of the page.  The browser will happily render the
> HTML as it receives it.  Assuming the header is quick
> to generate) a user gets instant feedback.   And for a long
> page, everything "above the fold" may be generated and rendered
> almost instantly even if it takes seconds to generate the rest
> of the HTML page that's not visible until scrolling down - and
> by the time the user does scroll down it'll be ready for him.

This is an optimization which tries to improve the "perceived
performance" for the user. It will do nothing to improve your servers
throughput. I'm much more after seeking improvements that increase
throughput.

>
> I'm too new to know how to do this in rails, though.

Currently this isn't possible with Rails. The page gets constructed as a
string, which is sent to the FCGI/SCGI pipe only after it has been
constructed in its entirety. Depending on your FCGI setup, you will see
parts being rendered before the entire page has been received by the
browser though.

-- stefan
91eb330fb36d1e03c856574dfb77d2bc?d=identicon&s=25 thibaut.barrere (Guest)
on 2005-11-30 09:44
(Received via mailing list)
> This is an optimization which tries to improve the "perceived
> performance" for the user. It will do nothing to improve your servers
> throughput. I'm much more after seeking improvements that increase
> throughput.

Perceived performance is also very important for customer
satisfaction... I
came to realise that part of my users prefer a more responsive UI (a
better
perceived performance) even at the cost of a slightly lower global
throughput... (that's not a reason for not optimizing the throughput
though
:-)

thibaut
E555e7c34196967444a47a96395a23ab?d=identicon&s=25 skaes (Guest)
on 2005-11-30 10:21
(Received via mailing list)
Thibaut Barrère wrote:

>throughput... (that's not a reason for not optimizing the throughput though
>
>
I didn't mean to imply that UI responsiveness isn't important. But if
your throughput isn't good enough, it won't help trying to improve
responsiveness. So my priorites are: throughput comes first, if this is
good enough, then you can look for improving responsiveness. In most
cases, once you've achieved satisfactory throughput, responsiveness
follows from lower server load.

-- stefan
616226cee3466e91febcd38f75c69194?d=identicon&s=25 helmut (Guest)
on 2005-11-30 12:18
(Received via mailing list)
Hi,

Am 30.11.2005 um 10:18 schrieb Stefan Kaes:
>>
> I didn't mean to imply that UI responsiveness isn't important. But if
> your throughput isn't good enough, it won't help trying to improve
> responsiveness. So my priorites are: throughput comes first, if this
> is good enough, then you can look for improving responsiveness. In
> most cases, once you've achieved satisfactory throughput,
> responsiveness follows from lower server load.

I think the responsiveness is one of the most important things. If it
is approached by a high throughput, well done.

The whole bunch of Ajax effects emerged just because of UI
responsiveness. So I would not say this "flush();" is the only way, but
it can help a lot. Most browser engines are built on the fact that most
internet connections are slow. They show the page incrementally. Just
sad that rails can't come up with this feature.

Helmut
4d03875f1716626c7e742ca0dd781836?d=identicon&s=25 jsierles (Guest)
on 2005-11-30 15:00
(Received via mailing list)
I must agree that the #1 perceived performance problem with Rails (and
lots of other web development kits) is directly related to the lack of
flushed output. While is essentially an illusion and probably not an
issue for a lot of 'applications', many 'public-facing' sites rely on
this sort of responsiveness, especially when a page is lamentably full
of advertising and other ignorable elements. However, this is a hard
problem to solve when you want to perform after filters, etc.

Having said that, it would be interesting to see a way to flush output
for 'optimized' pages, even if some Rails functionality is limited.
Would this technically be possible without radically modifying the way
the framework works?

Joshua Sierles
E555e7c34196967444a47a96395a23ab?d=identicon&s=25 skaes (Guest)
on 2005-11-30 16:34
(Received via mailing list)
Helmut Sedding wrote:

>> responsiveness follows from lower server load.
>
>
> I think the responsiveness is one of the most important things. If it
> is approached by a high throughput, well done.
>
> The whole bunch of Ajax effects emerged just because of UI
> responsiveness. So I would not say this "flush();" is the only way,
> but it can help a lot. Most browser engines are built on the fact that
> most internet connections are slow. They show the page incrementally.

If your pages are so slow that you need to flush your output buffer to
make them appear faster than they are, then you are in trouble.

> Just sad that rails can't come up with this feature.

I didn't say it couldn't be implemented. I simply think it's not worth
the added complexity, which is a slightly different position.

-- stefan
E555e7c34196967444a47a96395a23ab?d=identicon&s=25 skaes (Guest)
on 2005-11-30 16:58
(Received via mailing list)
Joshua Sierles wrote:

>I must agree that the #1 perceived performance problem with Rails (and
>lots of other web development kits) is directly related to the lack of
>flushed output. While is essentially an illusion and probably not an
>issue for a lot of 'applications', many 'public-facing' sites rely on
>this sort of responsiveness, especially when a page is lamentably full
>of advertising and other ignorable elements. However, this is a hard
>problem to solve when you want to perform after filters, etc.
>
>
Advertising is mostly implemented by embedding images in html, usually
retrieved from completely different servers. I can't see how flushing
your output buffer prematurely would help there.

>Having said that, it would be interesting to see a way to flush output
>for 'optimized' pages, even if some Rails functionality is limited.
>Would this technically be possible without radically modifying the way
>the framework works?
>
>
It would be necessary to make major changes to request processing, with
questionable value. One major drawback which immediately springs to mind
is that you would need to send out the request headers before knowing
whether the request can be fullfilled at all. This doesn't sound very
attractive to me.

I'm not convinced it's worth the implementation effort and there are a
number of other areas which I'd try to improve before diving into output
flushing, but I'll keep the suggestion in the back of my head.

-- stefan
F125beb53f6f585f5d327f09664a22cd?d=identicon&s=25 grant (Guest)
on 2005-11-30 17:18
(Received via mailing list)
Stefan Kaes wrote:

> Joshua Sierles wrote:
>
>> I must agree that the #1 perceived performance problem with Rails (and
>> lots of other web development kits) is directly related to the lack of
>> flushed output. While is essentially an illusion and probably not an
>> issue for a lot of 'applications', many 'public-facing' sites rely on
>> this sort of responsiveness, especially when a page is lamentably full
>> of advertising and other ignorable elements. However, this is a hard
>> problem to solve when you want to perform after filters, etc.
>
I have an application that the turnaround times were too slow, so I
solved it using AJAX.   It is a data entry application, and although the
turnaround times are good, the users wanted to be able to start typing
right away again.   I used AJAX to make the entry field blank
immediately, but fire the request to the server asynchronously.  This
way, every request happens, but the full feedback from it does not need
to happen before the next entry.   I have never seen it where the user
can type a whole new item before the response, but when forcing it to
happen (artificial load on the server and copy/paste for the entry item)
everything caught up and processed correctly.

I just used a remote form link and a little Javascript in the after on
the form_remote_tag to blank the field after the request was sent but
before the response got back.
A2b2f4ee23989dc68529baef9cbddcd6?d=identicon&s=25 listbox (Guest)
on 2005-12-06 20:20
(Received via mailing list)
On 30-nov-2005, at 12:15, Helmut Sedding wrote:

> Hi,
> <skip> So I would not say this "flush();" is the only way, but it
> can help a lot. Most browser engines are built on the fact that
> most internet connections are slow. They show the page
> incrementally. Just sad that rails can't come up with this feature.

This has to do with the way Rails (more specifically -
ActionController) work. Granted, you are not flushing output
incrementally but:

a) you can set headers anytime
b) your post-filtering is much more capable because you still can
modify the response as a whole
c) your page rendering is reversible (i.e. it's not working as a
stream) which eases things greatly

If you really want to do something like this you will need to
integrate your own stream-based templating that's going to be
synchronized with the actual output of the app, you will lose
response post-processing etc. But if you really want that, hell -
just render to string and send it away using streaming.

http://api.rubyonrails.org/classes/ActionControlle...

--
Julian 'Julik' Tarkhanov
me at julik.nl
Eea7ad39737b0dbf3de38874e0a6c7d8?d=identicon&s=25 justin (Guest)
on 2005-12-07 21:57
(Received via mailing list)
Julian 'Julik' Tarkhanov wrote:
> This has to do with the way Rails (more specifically -
> your own stream-based templating that's going to be  synchronized with
> the actual output of the app, you will lose  response post-processing
> etc. But if you really want that, hell -  just render to string and send
> it away using streaming.
>
> http://api.rubyonrails.org/classes/ActionControlle...

Recalling the thread "Newbie question about fastcgi scaling" back in
August, I don't think that this will work with FastCGI, either with
Apache, where the documentation for mod_cgi

    http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html

says that:

"FastCGI application output is buffered by default. This is not the case
for CGI scripts (under Apache 1.3). To override the default behavior,
use the -flush option (not available for dynamic applications)."

or with lighttpd, where Ben Myles (to support the discussion in the
thread) did a test that indicated the same was happening.

If this was not the case, it would appear to be trivial to mount a
denial of service attack on a Rails application, by opening many
connections and reading content from them very slowly. With static
allocation of FastCGI  processes (the favoured approach) the application
would stop handling requests as soon as all the processes were busy.
With dynamic allocation, things would slow down dramatically as the web
server spawned new processes (Rails has a long startup time), and memory
would eventually be exhausted (each FastCGI process uses tens of MB).

Thinking about this again now, I have the impression that serving large
(many MB) documents to unauthenticated users via send_data introduces
another hazard - if the web server is buffering the whole content while
the client downloads it, it would be easy to use many slow connections
to force memory exhaustion.

Has anyone looked into this?

regards

   Justin
89b61f93e1d880c518ab6e7c3e8b83f7?d=identicon&s=25 Jonathan Otto (Guest)
on 2005-12-07 22:08
If your rails apps are slow, check to see if you are running Apache web
server. I've found that since switching to Lighttpd, my apps are
significantly faster, I have noticed a HUGE difference.
621001962d9dfbdaae1436179ff6b2d6?d=identicon&s=25 dan.kubb-rails (Guest)
on 2005-12-10 11:32
(Received via mailing list)
Hi All,

I agree with others on this thread that there should be a way for a
view to render
the response incrementally, rather than the current behavior of
buffering the entire
response and sending it in a single step.

I disagree that the current approach results in higher throughput
than incremental
rendering would.

With the current approach you're buffering the entire response in
memory for every request.
If you are trying to handle a large number of clients and you start
swapping because memory
is used up, your performance is going to suffer.  Even if you don't
swap, the server still
has to use more memory than necessary to keep track of everything and
that certainly isn't
going to help performance any.

It takes more effort to keep track of the response body as you are
rendering it, than
just sending it out the pipe.  Not just in terms of memory, but in
terms of programming
effort.  In most cases its easier to render each chunk, send it to
the network, and
forget it.

Buffering at a lower level is useful, but let the webserver software
and the OS take
care of that.  As a general rule, for maximum throughput its better
to send whatever
information you have out the network than holding onto it and sending
it later.

Think about what would happen if each intermediary in the chain from
the app to
the client waited until the entire response was received and buffered
in memory
*and only then* handed it off to the next point in the chain.  For
example imagine
if at each of the following steps the entire response was received,
buffered, and
only passed onto the next chain *until* all of it had been received
in full:

   - Rails Application
   - SCGI/FastCGI
   - Back-end Web server
   - Front-end Reverse proxy server
   - Cache module on proxy server
   - GZIP Compression module on proxy server
   - SSL/TLS encryption module on proxy server
   - Web Proxy at client network gateway
   - Web Client (3 steps: SSL/TLS decryption, GZIP decompression,
Rendering)

Of course, I've taken this example to the extreme just to illustrate
a point that
if each step completely buffered the response before passing it on to
the next step,
a full round trip request would take a *really* long time.  In most
cases there would
likely not be this many steps.. but even with just 2 or 3 of them
doing complete
buffering, its easy to see how latency AND throughput would be
negatively affected.

Just be glad that most of these steps do not do things serially, they
are designed
to handle information in chunks, processing them, and yes sometimes
even doing
some buffering -- but only the smallest possible buffer that will
allow them to
do the job with reasonable performance.

In this thread, one of the approaches suggested send_data as a
solution.  This would
work, but why the need to be so explicit?  Why not have the ability
to pass in
a flag to render() that says you want the output flushed
incrementally as each
chunk of the view is rendered?  This would not only cut down memory
usage, but
would reduce the TTFB (Time to First Byte) so that the clients can
begin rendering
the output immediately.  Views could ignore the flag if they didn't
have the
capability of rendering in chunks, but for those that do, there would
be a nice
performance advantage -- I see no reason that existing Views couldn't be
updated in the future to accommodate incremental rendering.

I'd gladly give up the ability to use after_filter for this
capability.. even then,
it should be possible to create something like an after_stream_filter
that works
on the stream itself, allowing you to do transformations on the
output if you
really wanted to.  But like I said, this should be an option, for
people who
rely on after_filter, they would still need the in-memory buffering.

Sorry for the length of this post, but I'm coming in late and I
wanted to address
several points in a single message than break it across multiple
replies.

--

Thanks,

Dan
__________________________________________________________________

Dan Kubb                  Email: dan.kubb@autopilotmarketing.com
Autopilot Marketing Inc.  Phone: 1 (604) 820-0212
                             Web: http://www.autopilotmarketing.com
__________________________________________________________________
24d2f8804e6bb4b7ea6bd11e0a586470?d=identicon&s=25 jeremy (Guest)
on 2005-12-10 12:25
(Received via mailing list)
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Dec 10, 2005, at 2:30 AM, Dan Kubb wrote:
> In this thread, one of the approaches suggested send_data as a
> solution.  This would
> work, but why the need to be so explicit?  Why not have the ability
> to pass in
> a flag to render() that says you want the output flushed
> incrementally as each
> chunk of the view is rendered?

Please do implement.  Modifying Action Pack to stream output is
straightforward.  Its supporting libs (CGI, ERB, FastCGI) will take
more work, but could use the exercise.

Best,
jeremy
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (Darwin)

iD8DBQFDmrYlAQHALep9HFYRAlIVAKCkuVoRXlBVvaKYqZju8HwykaXt0ACdGHew
keEBjJCPHPkUJP5VNWdWFqU=
=U8H2
-----END PGP SIGNATURE-----
Dce47278b4de2597c378881b482d9cb6?d=identicon&s=25 ij.list (Guest)
on 2005-12-10 14:37
(Received via mailing list)
On Dec 10, 2005, at 12:04 PM, Jeremy Kemper wrote:

>> chunk of the view is rendered?
>
> Please do implement.  Modifying Action Pack to stream output is
> straightforward.  Its supporting libs (CGI, ERB, FastCGI) will take
> more work, but could use the exercise.

I really like the way Rails does layouts. This is the first sane
approach to layouts I have seen. Especially the way views can define
variables such @page_title, which are then used in layout. This means
that views (layout contents) must be rendered first, and only after
them the final layout is rendered.

How would you do layouts without buffering? Is there any point having
streaming-output-data if most of the processing (know of any
application that does not use layouts?) needs to be buffered anyway ?

Streaming really prevents a lot of nice current and future features,
which depend on out-of-order modifications, and has somewhat dubious
benefits (what kind of monster pages you need to have to see
significant benefits?). Streaming is natural approach for procedural
preprocessors, such as PHP. But Rails is not preprocessor. It is true
object-oriented MVC framework, and imposing streaming would cause
much complexity and/or feature-removal.

Streaming could be a nice and interesting hack, but with all the
possible bugs it would introduce and nice features it would prevent,
I would really prefer if it would be developed as a plugin, so it
would not influence Rails features and software quality...

Of course, all this is IMHO....

izidor
24d2f8804e6bb4b7ea6bd11e0a586470?d=identicon&s=25 jeremy (Guest)
on 2005-12-10 22:31
(Received via mailing list)
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Dec 10, 2005, at 5:35 AM, Izidor Jerebic wrote:
>> straightforward.  Its supporting libs (CGI, ERB, FastCGI) will
> for procedural preprocessors, such as PHP. But Rails is not
> preprocessor. It is true object-oriented MVC framework, and
> imposing streaming would cause much complexity and/or feature-removal.
>
> Streaming could be a nice and interesting hack, but with all the
> possible bugs it would introduce and nice features it would
> prevent, I would really prefer if it would be developed as a
> plugin, so it would not influence Rails features and software
> quality...


Agreed; however, it'd require some healthy examination of Action Pack
and the libraries it relies on.  If someone's gung-ho for the
feature, I welcome their effort.

Best,
jeremy
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (Darwin)

iD8DBQFDm0hcAQHALep9HFYRAtoIAJ0ZBflw5+kabSKTir0Ursbne4UKfACeMqCA
LxEiehazpvF84fllOmZlonM=
=lCI/
-----END PGP SIGNATURE-----
This topic is locked and can not be replied to.