STANDARDwalkthrough
Per-User Rate Limiting and Fatigue Control
The product teams do not coordinate. Growth schedules a re-engagement push, commerce fires a price-drop alert, and social sends two friend suggestions, all to the same user, all on Tuesday.
How do we cap the aggregate? A per-user, per-tier token bucket.
“Each send was individually reasonable; together they teach the user to disable notifications, and a disabled user is unreachable forever, including for OTPs.”
Every send request passes through a preference and budget check: P2 marketing draws from a bucket of 2 per day, P1 engagement from 10 per day with coalescing shrinking demand first, and P0 transactional bypasses budgets entirely because a user must always get their OTP. The bucket lives beside the dedup store: one Redis hash per user per day, incremented atomically at send time, roughly of daily counters with 48h TTL.
When the budget is exhausted, the send is not dropped silently: it degrades down the channel ladder: push becomes in-app inbox item, in-app becomes nothing for pure promotions. The business case is measurable: opt-out telemetry shows disable rates climbing sharply past 2 marketing pushes per day, and every 1% of users who disable push permanently removes them from all future campaigns, a compounding loss that dwarfs one campaign's clickthrough.
The trade-off: budgets create contention between product teams for scarce slots, which is a governance problem more than a technical one; most platforms solve it with per-team quotas inside the P2 budget. What if the interviewer asks: where does the check run, ingestion or send time?
Send time, after coalescing and quiet-hours shifting, because a message delayed into tomorrow must draw from tomorrow's budget. Checking at ingestion double-counts messages that later coalesce.
Related concepts