api-fairy

Build Status

api-fairy is a Rack Middleware that magically speeds up your slow backend services just by including it in your rack based application. It can be used to speed up API services with slow backends, but you can also use it in any generic rack apps including Ruby On Rails.

Differences with rack-cache

Rack::Cache focuses on HTTP caching by using http headers such as Expires or Cache-Control. This gem focuses on the other side of the coin where the backend responses and data are cached. This gem is a complement to Rack::Cache so you can speedup your application even more.

api-fairy packs the following features in a small package:

  • Localized dynamic cache. No memcache server needed.
  • Efficient memory usage. The memory usage rate is constant.
  • Multi-thread safe. Supports threaded ruby applications.
  • Works on ruby 1.8.7, 1.9.2, and 1.9.3
  • Small code base. Only 21 lines of code.
  • Dramatically increase your applciation speed by 5 - 10 times depending on the backend.
  • It literally turns your application into magic

Benchmark

Here is a brief benchmark on my company's API service without api-fairy:

Benchmarking localhost (be patient).....done


Server Software:
Server Hostname:        localhost
Server Port:            3000

Document Path:          /
Document Length:        60678 bytes

Concurrency Level:      5
Time taken for tests:   7.897 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Total transferred:      6087400 bytes
HTML transferred:       6067800 bytes
Requests per second:    12.66 [#/sec] (mean)
Time per request:       394.844 [ms] (mean)
Time per request:       78.969 [ms] (mean, across all concurrent requests)
Transfer rate:          752.79 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:   211  389  64.4    388     584
Waiting:      208  379  63.6    373     581
Total:        211  389  64.4    388     584

Percentage of the requests served within a certain time (ms)
  50%    388
  66%    415
  75%    432
  80%    448
  90%    462
  95%    504
  98%    552
  99%    584
 100%    584 (longest request)

With api-fairy:

Benchmarking localhost (be patient).....done


Server Software:
Server Hostname:        localhost
Server Port:            3000

Document Path:          /
Document Length:        5 bytes

Concurrency Level:      5
Time taken for tests:   1.187 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Total transferred:      12200 bytes
HTML transferred:       500 bytes
Requests per second:    84.24 [#/sec] (mean)
Time per request:       59.357 [ms] (mean)
Time per request:       11.871 [ms] (mean, across all concurrent requests)
Transfer rate:          10.04 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:     0   59 238.4      2    1092
Waiting:        0   57 238.5      0    1092
Total:          0   59 238.4      2    1092

Percentage of the requests served within a certain time (ms)
  50%      2
  66%      3
  75%      4
  80%      5
  90%     43
  95%   1092
  98%   1092
  99%   1092
 100%   1092 (longest request)

Note

Rubinus support will be included in the future.

Install

Bundler

gem "api-fairy", "= 0.4.1"

Usage

Using api-fairy is super easy. All you need to do is to use it in your config.ru:

require 'api-fairy'


# use your other middlewares here
# use Rack::Throttle::Hourly, :max => 1000

# must be your last rack middleware
use Rack::ApiFairy

run lambda {|env| [200, {'Content-Type' => 'text/plain'}, "Hello, world!\n"]}

Contributing to api-fairy

  • Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
  • Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
  • Fork the project.
  • Start a feature/bugfix branch.
  • Commit and push until you are happy with your contribution.
  • Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
  • Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.

Copyright (c) 2012 Aaron Qian. See LICENSE.txt for further details.