-
Notifications
You must be signed in to change notification settings - Fork 0
Rate Limits Explained
Every question costs you an API call, so the plugin limits how fast anyone can ask for them. Two limits apply to question generation, and one to answer submissions.
| Limit | Value | Scope |
|---|---|---|
| Per visitor | 5 per minute | Generation, keyed on IP address + browser User-Agent |
| Per IP | 15 per minute | Generation, keyed on IP address alone |
| Answers | 5 per minute | Answer submissions, per visitor |
Generation is charged against both generation limits. A visitor hits whichever runs out first.
The window is a fixed 60 seconds that resets on the minute boundary, not a rolling window. A practical consequence: five requests at 0:59 and five more at 1:01 are both allowed, so the real short-term burst ceiling is double the number in the table.
The per-visitor bucket includes the browser's User-Agent, which the caller controls. On its own, that means anyone could change one header and get a fresh allowance — an unbounded API bill from a single machine.
The per-IP ceiling closes that. It is keyed on the address alone, so rotating headers gets you nowhere. The finer per-visitor bucket is kept as well, so genuine visitors sharing one office IP are not lumped together at five per minute between them.
Please wait before requesting another question.
They do not see which limit they hit, or how long is left. The wait is at most 60 seconds.
The ai_fq_rate_limit filter receives the current limit and the bucket it applies to, so you can adjust each independently:
add_filter( 'ai_fq_rate_limit', function ( $limit, $bucket ) {
if ( str_starts_with( $bucket, 'generate-ip|' ) ) {
return 40; // per-IP ceiling
}
if ( str_starts_with( $bucket, 'generate|' ) ) {
return 10; // per-visitor generation
}
if ( str_starts_with( $bucket, 'answer|' ) ) {
return 10; // answer submissions
}
return $limit;
}, 10, 2 );Bucket prefixes are generate|, generate-ip| and answer|.
Zero and negative values are ignored. Returning 0 does not disable rate limiting — the plugin falls back to the default for that bucket. This is deliberate: the rate limiter is the only thing standing between a public endpoint and your provider bill, and a filter typo should not remove it.
There is no upper bound, so a large number effectively disables the limit. That is your decision to make, but understand what you are switching off.
Each widget fetches its own question when the page loads, and each fetch counts. A page with six widgets uses six of the per-visitor allowance immediately, so the sixth shows the wait message.
If you want a page of several widgets, raise the per-visitor generation limit to at least the number of widgets plus a little headroom for the visitor pressing "Next Question".
If your site sits behind Cloudflare or any reverse proxy, the address the plugin sees is the proxy's, not the visitor's. Every visitor then shares one per-IP ceiling, and 15 requests a minute across your whole audience is not enough.
This needs fixing or the widget will appear broken at scale. See Running Behind Cloudflare or a CDN.
Counters live in one table created on activation: a hashed bucket key, a window timestamp, and a count. No question text, no answers, nothing identifying.
An hourly scheduled task deletes rows older than a day, and each request clears its own stale windows, so the table does not grow.
If that table is missing, the limiter fails closed — every request is refused and every visitor sees the wait message permanently, even on an idle site. Deactivating and reactivating the plugin recreates it.
Getting started
- Home
- What AI Fun Questions Does
- Installing the Plugin
- The Settings Screen
- Adding the Widget to Your Site
Provider setup
Running it
- Keeping API Keys Out of the Database
- Rate Limits Explained
- Running Behind Cloudflare or a CDN
- What It Costs to Run
Troubleshooting
- Error Messages Reference
- Please Wait Before Requesting Another Question
- Could Not Generate a Question
Privacy and security
Extending