How the window works
Throttling is enforced in Redis:- When a survey modal is shown, the SDK calls
POST /v1/sdk/impression. The API writes a keythrottle:<projectId>:<userId>with a TTL ofthrottle_days × 86,400seconds (the shown survey’s window). - On every
POST /v1/sdk/eventandPOST /v1/sdk/evaluate, the API checks whether that key exists before any survey matching. If it exists, the API returnssurvey: nulland the SDK silently returns toidle.
- An impression (modal shown) is what starts the window — not the response. A user who closes the modal without answering is still throttled.
- A failed or abandoned response doesn’t undo the throttle: if the modal was shown, the impression already set the key.
- The window length is taken from the survey that was actually shown, so if two
surveys have different
throttle_days, the one shown wins for that user.
Tuning the window
In the survey builder, open the Trigger tab and set Minimum days between shows (thethrottle_days field). Range is 0–365; the default is 7.
Setting it to 0 disables throttling for that survey (useful for testing). It
takes effect on the next event/evaluate call.
Recommended settings:
Per-survey show caps
Separately from the project-wide time window, a survey can cap how many times it is ever shown to one user via the frequency → max shows per user setting. The API counts rows in theimpressions table for that (survey, respondent)
and stops matching once the cap is reached. Use this for “show this at most
twice, ever” rules that a time window can’t express.
Cross-survey behaviour
Since the throttle key is project-wide, two different surveys cannot both fire on the same user within the window — the first one shown blocks the rest. If you need surveys that can interleave more freely, keep their windows short or use separate projects.Testing without waiting
There’s no “reset throttling” button in the dashboard. To iterate during development:- Set the survey’s Minimum days between shows to
0. - Pass a fresh
userIdtoMicroSurvey.identify()each test session. - Or use a separate test project (its own API key).
Redis failures are non-fatal: if the throttle check can’t reach Redis, the API
treats it as “not throttled” and continues evaluating, and a failed impression
write still returns
200 (the impressions row is the source of truth).