How the window works
Throttling is enforced in Redis:- When a survey modal is shown, the SDK calls
POST /v1/sdk/impression. The API stores the time in a keythrottle:<projectId>:<surveyId>:<userId>. - On every
POST /v1/sdk/eventandPOST /v1/sdk/evaluate, the API skips a survey if it was shown to this user less than itsthrottle_daysago. The window is computed from the survey’s current setting, so a change in the dashboard applies on the next call.
- 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.
- Keys expire after 366 days. Erasing an end user (Privacy) deletes their keys immediately.
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 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
Each survey has its own window, so two different surveys can both be shown to the same user within a few days if both match. To keep users from seeing several surveys close together, give the surveys different triggers or audiences.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).