[Mongrel] Rails' send_file, Mongrel, and *gasp* memory

Ezra Zygmuntowicz ezmobius at gmail.com
Thu Dec 21 21:34:29 EST 2006

On Dec 21, 2006, at 2:15 PM, Jonathan Leighton wrote:

> I've had a right fun few days at work trying to figure out why our  
> Rails
> app (which isn't under very heavy load) kept eating memory and  
> bringing
> our server to our knees. Eventually I traced it to send_file (which  
> was
> in a way a relief as it wasn't down to my coding ;) -- every time a  
> user
> started downloading, the memory consumed by the app would jump, and
> wouldn't go down again, even when they had cancelled the download (I
> haven't tested whether the memory would still be consumed after they
> completed the download). This has become apparent recently as the app
> has been used for larger files (150MB and upwards). As a fix I've
> delegated file serving to lighttpd + mod_sec_download, not quite as
> convenient but probably better in the long run anyway.
> So the problem is solved, but I was just wondering why this  
> happened in
> the first place; according to the Rails docs, send_file buffers the
> response in order to not tie up memory. However, this was clearly not
> happening -- is this possibly related to how Mongrel interacts with
> Rails? If so, I gave it a try under lighttpd and still had the  
> problem,
> any idea why? I'm really just looking to understand the issue  
> better as
> I hate to walk away from a problem without fully comprehending it :)
> Thanks,
> -- 
> Jonathan Leighton, Web Developer

Hey -

	The rails send_file method is not the same thing as setting an X- 
SendFile header. If you are already using lighttpd for your server  
then your in good shape. THe rails send_file method actually does  
read the whole file into memory as it sends it to the client. SO you  
will see memory problems like you have if you use it on large files.  
The nice way to do it is to use the X-SendFile header in lighty. In a  
rails action that just wants to serve a static file from somewhere  
off the filesystem you can make it look like this:

def download
    file = File.find params[:file] # or whatever
    response.headers["X-Sendfile"] = file.path
    render :nothing => true

	When you enable X-SendFIle support in lighty it will see this empty  
response with just headers set and lighty will serve the static file  
fast. Here is a good blog post about something similar:


-- Ezra Zygmuntowicz 
-- Lead Rails Evangelist
-- ez at engineyard.com
-- Engine Yard, Serious Rails Hosting
-- (866) 518-YARD (9273)

More information about the Mongrel-users mailing list