Как посчитать email frequency fatigue в SQL
Содержание:
Зачем frequency fatigue
Если шлёте 5 писем в неделю, юзеры начинают пропускать → open rate падает. Шлёшь 7+ → unsubscribe растёт. Frequency fatigue — точка, где marginal letter перестаёт давать revenue и начинает съедать список. Маркетинг-команды часто оптимизируют volume, но не учитывают это.
Сигналы
- падающий open rate за неделю при росте sending volume
- рост unsubscribe rate
- рост spam complaints
- падение click-through
Frequency в SQL
WITH user_emails AS (
SELECT
subscriber_id,
DATE_TRUNC('week', sent_at)::DATE AS week,
COUNT(*) AS emails_sent,
COUNT(*) FILTER (WHERE was_opened) AS opens,
COUNT(*) FILTER (WHERE was_clicked) AS clicks,
MAX(CASE WHEN was_unsubscribed THEN 1 ELSE 0 END) AS unsubscribed
FROM email_log
WHERE sent_at >= CURRENT_DATE - INTERVAL '12 weeks'
GROUP BY subscriber_id, DATE_TRUNC('week', sent_at)
)
SELECT
emails_sent,
COUNT(*) AS users_at_this_volume,
AVG(opens::NUMERIC / emails_sent) * 100 AS avg_open_rate_pct,
AVG(unsubscribed) * 100 AS unsubscribe_rate_pct
FROM user_emails
GROUP BY emails_sent
ORDER BY emails_sent;Видно, как растёт unsubscribe с frequency.
Optimum frequency
Максимум revenue / unsubscribe trade-off:
WITH frequency_revenue AS (
SELECT
emails_sent,
SUM(revenue) / COUNT(DISTINCT subscriber_id) AS revenue_per_user,
AVG(unsubscribed) AS unsubscribe_rate
FROM email_revenue_view
GROUP BY emails_sent
)
SELECT
emails_sent,
revenue_per_user,
unsubscribe_rate * 100 AS unsub_pct,
revenue_per_user - unsubscribe_rate * 50 AS revenue_minus_churn_cost -- $50 = average LTV per unsubscribe
FROM frequency_revenue
ORDER BY revenue_minus_churn_cost DESC;Максимум revenue_minus_churn_cost = optimal sending frequency.
Personal frequency cap
Каждый customer имеет свой optimum:
WITH user_history AS (
SELECT
subscriber_id,
AVG(was_opened::INT) AS open_rate_at_current_freq,
COUNT(*) FILTER (WHERE sent_at >= CURRENT_DATE - INTERVAL '7 days') AS recent_emails
FROM email_log
WHERE sent_at >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY subscriber_id
)
SELECT
subscriber_id,
recent_emails,
open_rate_at_current_freq,
CASE
WHEN open_rate_at_current_freq < 0.05 AND recent_emails >= 5 THEN 'reduce_to_2_per_week'
WHEN open_rate_at_current_freq < 0.10 AND recent_emails >= 3 THEN 'reduce_to_1_per_week'
WHEN open_rate_at_current_freq > 0.25 AND recent_emails <= 2 THEN 'can_increase_to_3'
ELSE 'keep_current'
END AS recommendation
FROM user_history;Smart sending = разная частота для разных segments.
Частые ошибки
Ошибка 1. Frequency cap = same for all. Champion может получать 5 emails/week. Dormant — max 1. Сегментируйте.
Ошибка 2. Считать только open rate. MPP-inflated. Используйте click + revenue в knowledge base.
Ошибка 3. Оптимизировать только short-term. Daily emails дают peak revenue в неделю 1, но decay списка через 6 месяцев. Long-term view.
Ошибка 4. Не различать types. Transactional, newsletter, promo — разные fatigue thresholds.
Ошибка 5. Считать на all senders. Domain-aware: Gmail-юзеры терпят больше, чем Outlook. Сегментируйте.
Связанные темы
- Как посчитать unsubscribe rate в SQL
- Как посчитать email engagement score в SQL
- Как посчитать email open rate в SQL
- Как посчитать email list decay в SQL
FAQ
Сколько emails/week оптимум?
B2C: 1-3. B2B: 1-2. Daily — рискованно, нужны personalized triggers.
Frequency cap — что?
Maximum emails per period (e.g., 3/week). Cross-campaign enforcement.
Smart sending — это?
ML-based: алгоритм решает кому, что и когда. Brevo, Mailchimp Predictive.
Fatigue per segment?
Yes — VIP-segment может терпеть 5/week, casual — 1.
Когда suppress?
После 90 дней без open + 3+ emails sent — кандидат на suppression.