Agent Wranglers

Channels and preferences Required

Cap how many messages one person gets

Set a maximum number of push and text messages per person per day, and per type per hour. Fold the overflow into a digest or the inbox.

How to do it

Count sends per user and channel in a sliding window, for example in Redis or a sends table with an index on user and time. Start with caps such as 5 pushes and 2 marketing texts a day. Critical types do not count against the cap, but get their own cap to stop a loop, such as 20 a day. Alert when many users hit the cap at once, because that usually means a bug.

Example

-- Must return 0 rows
SELECT user_id, channel, count(*) FROM sends
WHERE sent_at >= now() - interval '1 day' AND urgency <> 'critical'
GROUP BY user_id, channel
HAVING count(*) > CASE channel WHEN 'push' THEN 5 WHEN 'sms' THEN 2 ELSE 1000 END;
const DAILY_CAP = { push: 5, sms: 2 };
export const underCap = async (userId, channel) =>
  (await db.sends.countSince(userId, channel, Date.now() - 86_400_000)) < (DAILY_CAP[channel] ?? Infinity);
from datetime import UTC, datetime, timedelta

DAILY_CAP = {"push": 5, "sms": 2}

def under_cap(user_id, channel):
    since = datetime.now(UTC) - timedelta(days=1)
    return db.sends.count_since(user_id, channel, since) < DAILY_CAP.get(channel, float("inf"))

How to check

A test sends 50 events of one type to one user in a minute. At most the cap goes out, and the rest land in the inbox. The sends table shows no user above the cap yesterday.

For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers notifications playbook: https://agentwranglers.se/playbook/notifications/channels-and-preferences/notification-rate-caps.