I decided to beef up my current infrastructure a bit by adding a proper caching layer to my blog.
Serious, my current blogging engine of choice, already generates proper HTTP Cache-Control headers as can be seen in its sinatra routing file:

  before do
    headers['Cache-Control'] = "public, max-age=#{Serious.cache_timeout}"
  end

Since I like to keep my application logic out of the webserver, I decided to use Ryan Tomayko’s rack-cache middleware.
While using the nginx-internal caching feature might be the faster solution, I like the feeling that I can actually read the sourcecode easily if I ever happen to encounter bugs.

When looking at the headers of my blog, you can now see a new attribute called “X-Rack-Cache”.
When hitting a page that wasn’t in the cache, it looks like this:

Age: 0  
X-Rack-Cache: miss, store

and if you happen to hit something cached, you’ll see this:

Age: 217  
X-Rack-Cache: fresh  

The “Age” header will tell you how many seconds ago the HTML had been generated. I currently set the maximum cache vaildity time to 300 seconds. If you happen to hit something in the cache that is OLDER than 300 seconds, you should see this:

Age: 0  
X-Rack-Cache: stale, invalid, store

Trying to see if the added caching actually made a difference was pretty satisfying:

Before

$ ab -kc 10 -t 30 http://blog.marc-seeger.de/
Server Software:        nginx/0.8.52
Concurrency Level:      10
Time taken for tests:   30.058 seconds
Complete requests:      420
Failed requests:        0
Write errors:           0
Keep-Alive requests:    420
Requests per second:    13.97 [#/sec] (mean)
Time per request:       715.662 [ms] (mean)
Time per request:       71.566 [ms] (mean, across all concurrent requests)
Transfer rate:          150.36 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   2.4      0      16
Processing:    89  704 873.3    530    9556
Waiting:       72  654 870.6    498    9539
Total:         89  705 873.5    530    9556

Percentage of the requests served within a certain time (ms)
  50%    530
  66%    572
  75%    613
  80%    671
  90%   1055
  95%   1448
  98%   2804
  99%   5267
 100%   9556 (longest request)

After

$ ab -kc 10 -t 30 http://blog.marc-seeger.de/

Server Software:        nginx/0.8.52
Concurrency Level:      10
Time taken for tests:   30.007 seconds
Complete requests:      7165
Failed requests:        0
Write errors:           0
Keep-Alive requests:    7099
Requests per second:    238.78 [#/sec] (mean)
Time per request:       41.880 [ms] (mean)
Time per request:       4.188 [ms] (mean, across all concurrent requests)
Transfer rate:          2203.54 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   1.6      0      18
Processing:    18   42  69.4     34    2433
Waiting:       17   39  64.9     32    2401
Total:         18   42  69.8     34    2433

Percentage of the requests served within a certain time (ms)
  50%     34
  66%     37
  75%     40
  80%     43
  90%     61
  95%     74
  98%     86
  99%    121
 100%   2433 (longest request)

Not too shabby :)

p.s. when configuring rack-cache, the “allow_reload” option should be set to false unless you want to allow everybody to forcefully ignore your cache.

Comments