Global rate limits and throttling in Discourse

Just curious as to what the conversations were that made this a consideration… any specific examples or patterns that you’ve seen emerge from existing customers?

In general we believe that everything should be rate limited: Rate Limiting and Velocity Checking. The reason that global per-ip rate limits were added was because users were finding creative ways around the existing rate limits.

For example, opening a very large number of tabs all at once creates a huge number of concurrent requests to the server. If global rate limiting is disabled your server will be hit by all those requests at once. Limiting this to a reasonable number allows you to open many tabs still, but not too many that your server has to start queueing the requests.

6 Likes

Hi Sam,
I have a couple of usability queries around the data returned from the API.

When I looked at the data returned from the API a couple of weeks ago, the back of period only appears to be accessible via the text which explains why the limiting is in place.

{"errors":["We have a daily limit on how many times that action can be
taken. Please wait 10 seconds before trying
again."],"error_type":"rate_limit"}

Is it possible to add a second error class (perhaps retry_delay or similar) which contains the number of seconds to back off as a separate field?

My second comment relates to the error pasted above - is it possible that ‘we have a daily limit’ is being used incorrectly, if I only need to wait another 10 seconds before I can try again? I’m guessing it should say “there is a limit on usage per X number seconds”.

thanks,
kk

2 Likes

Fixed …

And … fixed

9 Likes

Like lightning, thanks Sam!

I will try and test it in the next couple of days and see how I go.

1 Like

OK, will get it deployed a bit later today.

1 Like

Will it be possible to change this value from the admin panel? If these strict values are enabled by default and can not easily be changed by site admins, I fear I’ll have to do a really, really costly rewrite of the DiscourseMetrics backend.

2 Likes

no, sadly this is not planned, these settings are meant to be hard to amend. For hosting scenarios such as our hosting we are in control of this and not our customers.

5 Likes

Hi Sam,
Another query regarding the limits.

Is there an API endpoint we can query to proactively determine how many requests are permitted in a period of time?

There is not an API endpoint to check for number of requests left. The best method right now is to check the http status code for a 429 and then back off for the amount listed in the body of that response.

2 Likes

Hi Blake,

I was imaging something more proactive, for example:

  • I need to send 80 queries
  • I know i’m limited to something less than that
  • query to api.discourse/something
    -> oh, I can do 40 queries per minute
    -> better space my queries out over 2 minutes

Since there is nothing in that vein, I will simply rely on the 429 :slight_smile:
karl.

1 Like

Hi again,
I just spotted this response to a 429:

“You have performed this action too many times. Please wait 0 seconds before trying again.”

It smacks of off-by-one error somewhere - if it isn’t its a bit of an odd response.

1 Like

My guess is it’s a rounding error (please wait 0.4 seconds), but Sam would need to confirm.

1 Like

I think its more likely a rounding error. Will have a look at improving it so we pretend 1 if it is 0.1.

6 Likes

2 posts were split to a new topic: When rate limiting is hit return return a Retry-After header

Is there any way to change this setting? In app.yml maybe?

Is there any way to change this setting:

for a local installation on Mac OS following this guide?

It is set in config/discourse_defaults.conf. You should be able to set it as an environment variable when you start the rails server in development:

DISCOURSE_MAX_ADMIN_API_REQS_PER_KEY_PER_MINUTE=120 bundle exec rails s

$ DISCOURSE_MAX_ADMIN_API_REQS_PER_KEY_PER_MINUTE=120 bundle exec rails c
Loading development environment (Rails 5.2.2)
[1] pry(main)> GlobalSetting.max_admin_api_reqs_per_key_per_minute
=> 120
[2] pry(main)> 
5 Likes

It works! Thank you very much!

4 Likes

This is what I’ve been looking for!!! We have a bot (set as admin) on Discourse that is performing many requests for our API backend. I would like to know if the Discourse group plans to put this in admin settings or is there somewhere already?

The main reason is that we have providers hosting our Discourse site… so it’s a redeployment from what I understand (changing config files).