# Rails URLs always try to open non-existent files

**URL:** <https://www.ruby-forum.com/t/rails-urls-always-try-to-open-non-existent-files/52440>\
**Category:** Rails\
**Created:** [January 14, 2006, 2:17am UTC](https://www.ruby-forum.com/t/rails-urls-always-try-to-open-non-existent-files/52440 "2006-01-14T02:17:29Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![hotjuneshen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/f19dbf/32.png) [@hotjuneshen](https://www.ruby-forum.com/u/hotjuneshen)\
**Post date:** [January 14, 2006, 2:17am UTC](https://www.ruby-forum.com/t/rails-urls-always-try-to-open-non-existent-files/52440/1 "2006-01-14T02:17:29Z")

</div>

The lighttpd config file is set up like this…

Rails url: //host/controller/method/id  
Lighttpd tries to open the file ‘controller/method/id’ from the document  
root.  
Of course this doesn’t work and generates an error 404  
This gets caught with: server.error-handler-404 = “/dispatch.fcgi”  
Which turns the request into “/dispatch.fcgi”  
That gets caught by: fastcgi.server = (".fcgi" =\>…  
And it finally ends up in Rails.

Apache is doing similar work with:  
RewriteCond %{REQUEST\_FILENAME} !-f  
RewriteRule ^(.\*)$ dispatch.fcgi [QSA,L]

Why aren’t the servers setup to mount the app someplace like ‘app’ and  
avoid all of this indirection? You can use fastcgi.server = ("/app" =\>  
to route all URLs starting with ‘app’ into Rails.

Other than letting you use ‘//host/controller/method/id’ instead of  
‘//host/app/controller/method/id’ is there some other advantage to  
trying to open the file first?

–  
Jon S.  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![hotjuneshen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/f19dbf/32.png) [@hotjuneshen](https://www.ruby-forum.com/u/hotjuneshen)\
**Post date:** [January 14, 2006, 6:15am UTC](https://www.ruby-forum.com/t/rails-urls-always-try-to-open-non-existent-files/52440/2 "2006-01-14T06:15:17Z")

</div>

> Rails url: //host/controller/method/id  
> Lighttpd tries to open the file ‘controller/method/id’ from the  
> document root.  
> Of course this doesn’t work and generates an error 404  
> This gets caught with: server.error-handler-404 = “/dispatch.fcgi”  
> Which turns the request into “/dispatch.fcgi”  
> That gets caught by: fastcgi.server = (".fcgi" =\>…  
> And it finally ends up in Rails.

And how long does this take? Measure it.

My machine is a PowerBook G4 (1.67Ghz, 5,400RM laptop HD using HFS+)  
running Lighttpd and setting the 404 handler to a static HTML file.  
The file is 36kb so the network transfer isn’t an issue.

apachebench -n 5000 -c 5 gives me:  
Requests per second: 1356.48 [#/sec] (mean)  
For a direct request:  
Requests per second: 1566.91 [#/sec] (mean)

As for a network drive:  
Requests per second: 119.37 [#/sec] (mean)  
vs  
Requests per second: 173.03 [#/sec] (mean)

This is for the same machine above accessing a directory mounted via  
AFP over an 802.11g wireless connection. Hardly fast. The remote  
server has a standard 80GB 7,200RPM hard drive using ReiserFS. Unless  
you’re Yahoo or someone you won’t need to care, and I’d assume that  
anyone actually running an app will use a decent fileserver with fast  
interconnects and mount drives with NFS.

The bottom line is that the redirection doesn’t take any time worth  
caring about.

> Why aren’t the servers setup to mount the app someplace like ‘app’ and  
> avoid all of this indirection? You can use fastcgi.server = ("/app" =\>  
> to route all URLs starting with ‘app’ into Rails.

Yes, you can, but…

> Other than letting you use ‘//host/controller/method/id’ instead of  
> ‘//host/app/controller/method/id’ is there some other advantage to  
> trying to open the file first?

Page caching. Typo caches all blog posts as a whole action, so it’s  
saved as a file. If you get slashdotted the majority of page requests  
go like this:  
Lighttpd finds file, sends file  
Rather than  
Lighttpd forwards request to Rails app  
Rails app finds file  
Rails add sends file to Lighttpd  
Lighttpd sends file to client.

This is Rails serving a static .rhtml file, same machine as above,  
served from localhost:  
Requests per second: 5.52 [#/sec] (mean)

If you want speed keep it outside of Rails. If you’re serving dynamic  
pages the little bit of indirection costs very little compared to DB  
queries and starting up a Rails app.

---

<div class="post-metadata">

**Author:** ![hotjuneshen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/f19dbf/32.png) [@hotjuneshen](https://www.ruby-forum.com/u/hotjuneshen)\
**Post date:** [January 14, 2006, 7:18pm UTC](https://www.ruby-forum.com/t/rails-urls-always-try-to-open-non-existent-files/52440/3 "2006-01-14T19:18:45Z")

</div>

On 1/14/06, Phillip H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> saved as a file. If you get slashdotted the majority of page requests  
> Requests per second: 5.52 [#/sec] (mean)  
> That’s the answer I was looking for, it’s how page caching is  
> implemented. I hadn’t discovered page caching in Rails yet so I  
> couldn’t explain the check for the non-existent files. Now that I’ve  
> ready up on page caching it makes perfect sense.

–  
Jon S.  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![hotjuneshen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/f19dbf/32.png) [@hotjuneshen](https://www.ruby-forum.com/u/hotjuneshen)\
**Post date:** [January 21, 2006, 3:40pm UTC](https://www.ruby-forum.com/t/rails-urls-always-try-to-open-non-existent-files/52440/4 "2006-01-21T15:40:22Z")

</div>

On 1/13/06, Ezra Z. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Jon-
> 
> ```
> Rails does this so that it can serve static files like stylesheets
> 
> ```
> 
> and images and cached pages as well, without going through rails.  
> Page caching wouldn’t work ar be anywhere near as fast if it had to  
> go through rails first. The amount of time it takes for a webserver  
> to see if a file exists is infinitesimal and isn’t really an issue to  
> worry about.

You could leave your public directory alone, all of the URLs for  
images, stylesheets, etc would stay the same. Only the URLs for Rails  
generated pages would change, instead of //host/controller/id it would  
be //host/app/controller/id. The the server would key off /app.

Right now the Rails names space in mixed into the public namespace.  
The only way to make things work is to first check for existence in  
the public namespace and then if it isn’t there use the Rails  
namespace.

So far the only two advantages to this I see are:

1. you don’t have to add ‘/app’ to the URL
2. you can replace a Rails generated page by placing a static one in  
front of it in the public hierarchy.

Checking for non-existence of files doesn’t take a lot of time but it  
is not free on SMP systems or if the file system is on a network  
mount.

–  
Jon S.  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![hotjuneshen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/f19dbf/32.png) [@hotjuneshen](https://www.ruby-forum.com/u/hotjuneshen)\
**Post date:** [January 21, 2006, 3:40pm UTC](https://www.ruby-forum.com/t/rails-urls-always-try-to-open-non-existent-files/52440/5 "2006-01-21T15:40:21Z")

</div>

On Jan 13, 2006, at 4:58 PM, Jon S. wrote:

> trying to open the file first?
> 
> –
> 
> Jon S.

Jon-

```
Rails does this so that it can serve static files like stylesheets

```

and images and cached pages as well, without going through rails.  
Page caching wouldn’t work ar be anywhere near as fast if it had to  
go through rails first. The amount of time it takes for a webserver  
to see if a file exists is infinitesimal and isn’t really an issue to  
worry about.

Cheers-  
-Ezra Z.  
Yakima Herald-Republic  
WebMaster  
[http://yakimaherald.com](http://yakimaherald.com)  
509-577-7732  
removed\_email\_address@domain.invalid
