Dashboard widgets fire all requests to /organizations/{orgSlug}/events-stats/ simultaneously on page load, exhausting the per-org concurrent query budget. Widgets that lose the race receive a 429 Too Many Requests response and render as failed charts, with no retry and no user-facing indication that rate limiting is the cause. Because requests race on each load, the failing widgets rotate randomly, making the issue hard to diagnose.
Symptoms
- Intermittently failed/blank charts on widget-heavy dashboards (rotating on each reload)
429 responses on events-stats visible in browser network tab
- Affects first load, not just repeated refreshes — concurrency alone is sufficient to trigger it
- Heavier queries amplify the problem (e.g.
statsPeriod=7d, multiple groupBy fields)
Root cause (high confidence)
The dashboard fetches all widget data in parallel with no concurrency limit or request queue. The per-org rate limit on events-stats is hit before all widgets can start, and the frontend has no backoff or retry logic for 429 responses.
Two gaps to address
- No request staggering or queue — widgets should not fan out all at once; a concurrency cap or sequential queue would prevent saturation
- Silent failure on 429 — failed widgets show a generic error with no indication that rate limiting is the cause; a
429-specific message and automatic retry would significantly improve the UX
Workaround
Split large dashboards into smaller ones with fewer widgets, and reduce statsPeriod to lower per-query cost.
Action taken on behalf of Angelo de Voer.
Dashboard widgets fire all requests to
/organizations/{orgSlug}/events-stats/simultaneously on page load, exhausting the per-org concurrent query budget. Widgets that lose the race receive a429 Too Many Requestsresponse and render as failed charts, with no retry and no user-facing indication that rate limiting is the cause. Because requests race on each load, the failing widgets rotate randomly, making the issue hard to diagnose.Symptoms
429responses onevents-statsvisible in browser network tabstatsPeriod=7d, multiplegroupByfields)Root cause (high confidence)
The dashboard fetches all widget data in parallel with no concurrency limit or request queue. The per-org rate limit on
events-statsis hit before all widgets can start, and the frontend has no backoff or retry logic for429responses.Two gaps to address
429-specific message and automatic retry would significantly improve the UXWorkaround
Split large dashboards into smaller ones with fewer widgets, and reduce
statsPeriodto lower per-query cost.Action taken on behalf of Angelo de Voer.