Paging Dr. Cache
When I launched this blog last week I thought it was slow because of my small (256MB) Slice at Slicehost. Then I read about people optimizing their rails installations, so I optimized and it got a bit faster. But, it was still slow. So I read up on optimizing the speed and memory usage of Phusion Passenger aka mod_rails. I made some enhancements and it got a bit better. Problem was, it was still REALLY slow. For a second I got a bit discouraged, I thought to myself “Is this the kind of performance I can expect from a simple rails app?”, I quickly reminded myself that I was probably just not realizing that there was something I could do to make things faster. Then I remembered something I read about caching.
Page Caching is EZ
Following the super-duper-awesome page caching tutorial on the RailsEnvy blog, I quickly setup some caching for my posts controller. I also got my sweepers happening to make sure I’m not serving my guests anything old and stale (bad host indeed).
class PostsController < ApplicationController ... caches_page :index, :show cache_sweeper :post_sweeper, :only => [:create, :update, :destroy] ...
All together it took about 15 minutes, I spent some extra time troubleshooting a problem that was the result of naming my sweeper PostSweeper.rb rather than post_sweeper.rb.
mod_rails configuration
In the RailsEnvy tutorial they mention setting up some custom mod_rewrite rules to handle telling Apache to serve your cached pages instead of passing the requests on to your mongrel instance. From what I read in the Passenger/mod_rails user guide, this wasn’t necessary, plus they mention that mod_rails doesn’t play well with mod_rewrite anyhow, so I didn’t change anything about my vhost config.
PLS 2 BEE BENCHMRKIN
I read all about how cool and fast page caching was and not that I didn’t believe it, but I was curious how cool and fast it really was. To test any performance improvements I used Apache Benchmark (ab for short).
The test consisted of running 500 requests with a concurrency level of 5
$> ab -c 5 -n 500 http://www.lengelzigich.com/
I ran this three times from start to finish, waiting about 30 seconds between each run. Then I ran it a fourth time and saved those results.
Before Page Caching
Server Software: Apache
Server Hostname: www.lengelzigich.com
Server Port: 80
Document Path: /
Document Length: 4599 bytes
Concurrency Level: 5
Time taken for tests: 92.220691 seconds
Complete requests: 500
Failed requests: 2
(Connect: 2, Length: 0, Exceptions: 0)
Write errors: 0
Total transferred: 2552000 bytes
HTML transferred: 2299500 bytes
Requests per second: 5.42 [#/sec] (mean)
Time per request: 922.207 [ms] (mean)
Time per request: 184.441 [ms] (mean, across all concurrent requests)
Transfer rate: 27.02 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 74 392 2023.8 78 19114
Processing: 96 115 34.8 103 536
Waiting: 94 111 24.8 100 207
Total: 172 508 2022.9 183 19215
Percentage of the requests served within a certain time (ms)
50% 183
66% 187
75% 199
80% 223
90% 249
95% 276
98% 7114
99% 11201
100% 19215 (longest request)
After Page Caching
Server Software: Apache
Server Hostname: www.lengelzigich.com
Server Port: 80
Document Path: /
Document Length: 4602 bytes
Concurrency Level: 5
Time taken for tests: 24.150369 seconds
Complete requests: 500
Failed requests: 0
Write errors: 0
Total transferred: 2553500 bytes
HTML transferred: 2301000 bytes
Requests per second: 20.70 [#/sec] (mean)
Time per request: 241.504 [ms] (mean)
Time per request: 48.301 [ms] (mean, across all concurrent requests)
Transfer rate: 103.23 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 74 88 180.5 78 4008
Processing: 95 119 36.3 105 494
Waiting: 93 116 35.4 103 492
Total: 171 208 183.2 186 4109
Percentage of the requests served within a certain time (ms)
50% 186
66% 192
75% 202
80% 218
90% 247
95% 261
98% 277
99% 392
100% 4109 (longest request)
The Results
- 4x improvement in requests per second
- Time per request reduced by 75%
- 100% of requests were served in 4 seconds or less compared to 15 seconds or less
Overall I’m more than pleased with the results and plan on taking a look at the next RailsEnvy tutorial on ActionCaching.












