How to do it...

Follow these steps for rate limiting:

  1. Firstly, we need to define a shared memory space to use for tracking the IP addresses. This needs to be added in the main configuration file, outside the standard server block directive. Here's our code:
      limit_req_zone $binary_remote_addr zone=basiclimit:10m rate=10r/s; 
  1. Then, within the server block, you can set which location you wish to limit. Here's what our server block directive looks like:
      server { 
          listen       80; 
          server_name  limit.nginxcookbook.com; 
          access_log  /var/log/nginx/limit-access.log  combined; 
 
          location / { 
              limit_req zone=basiclimit burst=5; 
              proxy_pass http://127.0.0.1:8000; 
              proxy_set_header X-Forwarded-For 
$proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; } }
  1. We can run Apache Benchmark (a simple web benchmarking tool) under a few different scenarios to test the effectiveness. The first is to use a single connection and make 200 requests:
      ab -c 1 -n 200 http://limit.nginxcookbook.com/

This gives us the following results:

      Concurrency Level:      1
      Time taken for tests:   20.048 seconds
      Complete requests:      200
      Failed requests:        0
      Total transferred:      5535400 bytes
      HTML transferred:       5464000 bytes 
      Requests per second:    9.98 [#/sec] (mean) 
      Time per request:       100.240 [ms] (mean) 
      Time per request:       100.240 [ms] (mean, across all concurrent 
requests) Transfer rate: 269.64 [Kbytes/sec] received

As the results show, we didn't receive any errors and averaged 9.98 requests per second.

  1. In the next test, we'll increase the number of concurrent requests to 4 at a time:
      ab -c 4 -n 200 http://limit.nginxcookbook.com/

This gives us the following results:

      Concurrency Level:      4 
      Time taken for tests:   20.012 seconds 
      Complete requests:      200 
      Failed requests:        0 
      Total transferred:      5535400 bytes 
      HTML transferred:       5464000 bytes 
      Requests per second:    9.99 [#/sec] (mean) 
      Time per request:       400.240 [ms] (mean) 
      Time per request:       100.060 [ms] (mean, across all concurrent 
requests) Transfer rate: 270.12 [Kbytes/sec] received

Even with the increased request rate, we still received responses at a rate of 10 requests per second.