The legitimate customers of my website from time to time hammer the server with API demands that create undesirable results. I wish to institute a restriction of a maximum of say one API call every 5 seconds or n calls each minute (haven't determined the precise limit yet). I possibly could clearly log every API get in touch with a DB and perform the calculation on every request to ascertain if they are within the limit, but all of this extra overhead on EVERY request could be beating the reason. What exactly are other less resource-intensive techniques I possibly could use to institute a restriction? I am using PHP/Apache/Linux, for which it's worth.
Ok, there is no method of doing things i requested without any creates towards the server, however i can at any rate eliminate logging each and every request. One of the ways is to apply the "leaking bucket" throttling method, where it only monitors the final request (
$last_api_request) along with a ratio of the amount of demands/limit for that time period (
$minute_throttle). The leaking bucket never starts over its counter (unlike the Twitter API's throttle which starts over every hour), but when the bucket becomes full (user arrived at the limit), they have to wait
n seconds for that bucket to empty just a little before they are able to make another request. Quite simply it's just like a moving limit: if you will find previous demands inside the time period, they're gradually seeping from the bucket it only limits you should you fill the bucket.
This code snippet will calculate a brand new
$minute_throttle value on every request. I specified the minute in
$minute_throttle since you can add throttles for just about any period of time, for example hourly, daily, etc... although several will rapidly start making it confusing for that customers.
$minute = 60 $minute_limit = 100 # customers are restricted to 100 demands/minute $last_api_request = $this->get_last_api_request() # achieve with a home DB in epoch seconds $last_api_diff = time() - $last_api_request # within minutes $minute_throttle = $this->get_throttle_minute() # achieve with a home DB if ( is_null( $minute_limit ) ) else preferred: $minute_hits_remaining = $minute_hits_remaining >= ? $minute_hits_remaining : if ( $new_minute_throttle > $minute ) demands continues to be exceeded. Please wait ' . $wait . ' seconds before trying again.' ) ) # Save the values to the database. $this->save_last_api_request( time() ) $this->save_throttle_minute( $new_minute_throttle )
You state that "all thos extra overhead on EVERY request could be beating the reasonInch, but I am unsure that's correct. Is not the reason to avoid hammering of the server? This really is most likely the way in which I'd implement it, because it really only takes a quick read/write. You can even farm the API server inspections to another DB/disk should you be concerned about the performance.
However, if you would like options, you can examine out mod_cband, another-party apache module designed to assistance with bandwidth throttling. Despite being mainly for bandwidth restricting, it may throttle according to demands-per-second too. I have not used at all it, so I am unsure what type of results you'd get. There is another module known as mod-throttle too, but that project seems to become closed now, and never was launched for anything over the Apache 1.3 series.
Easiest solution is always to just give each API key a restricted quantity of demands per 24 hrs, and totally reset them at some known, fixed, time.
When they exhaust their API demands (ie. the counter reaches zero, or even the limit, with respect to the direction you are counting), stop serving them data before you totally reset their counter.
By doing this, it will likely be in their welfare not to hammer you with demands.