Гігієна списку розсилки: як сегментувати неактивних, повертати їх і безпечно видаляти адреси
Неактивні підписники не займають місце в базі — вони ламають доставність усіх ваших листів. Розбираємо сегментацію dormant-адрес, throttled re-engagement воронку та suppression замість DELETE, з SQL, DSN-кодами й порогами Google/Yahoo 2026.
EvilMail Team12 липня 2026 р.12 хв читання
Чому неактивні адреси коштують вам доставності, а не місця в базі
Типова картина: контент розсилки не змінювався місяцями, тема та сама, дизайн той самий, а folder placement у Gmail раптом їде з «Основних» у «Промоакції», потім у «Спам». Заходите в Google Postmaster Tools — а там Domain reputation опустилася з High до Medium, і графік Spam rate тихо повзе вгору. Ви нічого не міняли. І саме в цьому проблема.
Gmail і Microsoft давно не оцінюють пошту за словником стоп-слів. Вони зважують поведінку отримувачів: чи відкривають, чи відповідають, чи натискають «Не спам», чи видаляють не читаючи, скільки лист лежить у папці. Це і є engagement. І тут спрацьовує арифметика, яку маркетинг ігнорує: коли ви шлете на 100 тисяч адрес, з яких реально живих 30 тисяч, ви розбавляєте всі позитивні сигнали 70 тисячами тиші. Провайдер бачить домен, який регулярно шле пошту людям, котрим вона байдужа, — і знижує репутацію для всіх листів разом, включно з тими 30 тисячами, які вас чекають.
Гірше: покинуті адреси не залишаються нейтральними. Через 6–12 місяців бездіяльності mailbox-провайдер може реактивувати стару адресу як recycled spam trap — вона знову приймає пошту, але кожен лист туди фіксується як влучання в пастку. Поряд існують pristine traps (адреси, що ніколи не належали людині, розкидані для лову скрейплених баз) і typo traps на кшталт
Гігієна списку розсилки: сегментація, re-engagement і безпечне видалення адрес — EvilMail Blog
gmial.com
. Ваш dormant-сегмент — головний кандидат перетворитися на recycled trap просто через час.
Орієнтири, від яких відштовхуємось у 2026-му (bulk sender rules Google/Yahoo для доменів, що шлють понад 5000 листів на день):
Spam complaint rate < 0.30% стабільно, в ідеалі < 0.10%. Разовий стрибок вище 0.30% уже карається.
Hard bounce < 2%, ціль < 1%.
SPF + DKIM + DMARC — обов'язкові, не опційні.
List-Unsubscribe + List-Unsubscribe-Post (one-click, RFC 8058) — обов'язкові в кожному bulk-листі.
За таких порогів стратегія «зберігаємо всіх про всяк випадок» технічно неможлива. Гігієна списку — не генеральне прибирання раз на рік, а безперервний конвеєр із трьома станами адреси.
Що таке «неактивний»: межа за даними, а не на око
Єдиного порогу «90 днів» не існує. Вікно неактивності залежить від частоти розсилки: для щоденної газети мовчання 30–60 днів — це вже тривога; для щотижневого дайджесту норма 90 днів; для щомісячного продукту адреса може «прокинутись» і через 180+ днів. Транзакційні листи (підтвердження, скидання пароля, чеки) у цю логіку не входять взагалі — їх шлемо завжди.
Робоча матриця станів, яку варто закладати в схему даних:
Active — є open або click за останні N днів згідно з вашою частотою.
Lapsing — engagement зник, але й негативу немає. Найцінніший сегмент для повернення.
Dormant — нуль engagement за 2+ повні цикли розсилки. Кандидат у recycled trap.
Never-engaged — нуль з моменту підписки. Окрема каста й найтоксичніша: це часто боти, disposable-адреси або друкарські помилки, що просочилися крізь слабкий double-opt-in. Їх не «повертають» — їх сегментують агресивніше й відправляють у suppression раніше за всіх.
Сегментація починається з двох простих запитів. Тримайте на підписнику last_engaged_at (оновлюється при open/click) і created_at:
sql
-- lapsing: були активні, замовкли (свіжий пул для re-engagement)
SELECT id, email FROM subscribers
WHERE status = 'active'
AND last_engaged_at < now() - interval '90 days'
AND last_engaged_at > now() - interval '180 days';
-- never-engaged: жодного сигналу з моменту підписки (найтоксичніші)
SELECT id, email FROM subscribers
WHERE status = 'active'
AND last_engaged_at IS NULL
AND created_at < now() - interval '30 days';
Never-engaged свідомо відокремлюємо: змішати їх у загальну «повертальну» кампанію — значить одним залпом ударити по найгіршому сегменту й отримати сплеск скарг.
Технічна гігієна ДО сегментації: bounce, complaints, пастки
Перш ніж рахувати engagement, приберіть сміття на рівні SMTP — інакше ви сегментуєте адреси, яких фізично не існує. Правило просте: 5.x.x → hard, 4.x.x → лічильник.
5.1.1 user unknown — hard, у suppression одразу.
5.2.1 mailbox disabled — hard.
5.2.2 mailbox full — трактуємо як soft (може звільнитись), лічильник.
4.2.2 over quota — soft, retry.
4.7.x greylisting / rate / policy — soft.
5.7.1 blocked / policy — розбирати вручну: це може бути репутація, а не мертва адреса.
На Postfix bounced-рядки в логах несуть готовий enhanced-код у полі dsn=, звідти й агрегуйте:
bash
grep 'status=bounced' /var/log/mail.log \
| grep -oE 'dsn=[45]\.[0-9]+\.[0-9]+' | sort | uniq -c | sort -rn
# деталі конкретного повідомлення (поки воно ще в черзі):
postcat -q A1B2C3D4 | grep -iE 'status|diagnostic'
Soft bounce — не привід одразу викидати. Заведіть колонку soft_bounce_count: при 4.x.x робите +1, при першій успішній доставці — скидаєте в 0, а на п'ятому поспіль — пишете в suppression з причиною soft_bounce_limit.
Скарги (FBL) обробляються жорсткіше за bounce: скарга — це прямий сигнал провайдеру, і кожна тягне ваш complaint rate до тієї межі 0.30%. Тут є нюанс: Gmail класичного per-message FBL не дає — лише агрегований Spam rate у Postmaster Tools. А от Yahoo/AOL (CFL) та Microsoft (JMRP + SNDS) дають, і їх треба зареєструвати на домен та IP. Будь-яка скарга з FBL = миттєвий unsubscribe + suppress з причиною complaint.
Окремий кут, який ми в evilmail знаємо зсередини, бо самі видаємо тимчасові адреси: disposable-домени в базі — це гарантований hard bounce і пастка репутації. Ловити їх треба не в розсилці, а на етапі збору, у момент сабміту форми:
bash
# 1. синтаксис за RFC 5322 (робіть у коді)
# 2. чи взагалі приймає пошту домен:
dig MX mailinator.com +short
# 3. звірка з disposable-словником (mailinator, guerrillamail, temp-mail...)
# 4. reject role-адрес для маркетингу: admin@, noreply@, postmaster@
Один MX-lookup і словник одноразових доменів на формі економлять вам місяці боротьби з репутацією потім.
Re-engagement кампанія, яка повертає, а не добиває
Найпоширеніша помилка — розіслати «ми за вами скучили» одразу по всьому dormant-пулу. Це технічне самогубство: ви одним махом б'єте по найгіршому сегменту, отримуєте сплеск скарг і hard bounce, і провайдер фіксує різкий стрибок негативу на домені. Репутація падає швидше, ніж встигає повернутись бодай хтось.
Правильний підхід — throttled ramp з ізольованого субдомену. Розсилайте повертальну кампанію з окремого news.evilmail.pro із власним DKIM-селектором, щоб репутація цієї ризикованої кампанії не текла на транзакційний mail.evilmail.pro. Warmup батчами: 50 → 200 → 1000, і між кожним батчем дивитеся Spam rate у Postmaster. Якщо на 200 скарги пішли вгору — не збільшуєте, а зупиняєтесь.
Починаєте з найсвіжіших lapsing, а не з глибокого dormant. Воронка — три листи за 2–3 тижні:
1.Нагадування цінності: що людина отримує, конкретна користь.
2.Стимул + оновлення преференцій: знижена частота, вибір тем, а не просто «залишись».
3.Фінальний: «підтвердіть, інакше ми відпишемо вас самі» — з реальним дедлайном.
Метрики виходу з воронки чіткі: хто клікнув або оновив преференції — повертається в active; хто промовчав усі три листи — йде в sunset. І замість кнопки повного unsubscribe ведіть на preference center: часто людина не хоче зникнути, вона хоче отримувати рідше. Це рятує адресу замість того, щоб її втратити.
Sunset policy: безпечне видалення без «DELETE FROM subscribers»
Головна технічна теза всієї статті: ніколи не робіть hard DELETE. Причини дві. Перша — ви втрачаєте історію: чому адреса пішла, коли, з якою скаргою. Друга і важливіша — видалена адреса повернеться. Наступний імпорт із CRM, вебінару чи старого CSV занесе її знову, і вона знову битиме, знову ловитиме trap, знову тягнутиме репутацію.
Правильна модель — окрема suppression-таблиця, яку mailer перевіряє перед кожною відправкою:
sql
CREATE TABLE email_suppression (
email CITEXT PRIMARY KEY,
reason TEXT NOT NULL, -- hard_bounce | complaint | unsubscribe | sunset | manual
bounce_code TEXT,
suppressed_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX idx_suppression_reason ON email_suppression(reason);
-- pre-send guard: беремо тільки тих, кого немає в suppression
SELECT s.id, s.email
FROM subscribers s
LEFT JOIN email_suppression e ON e.email = s.email
WHERE s.status = 'active' AND e.email IS NULL;
Sunset запускається як cron/queue-джоба, обов'язково ідемпотентна: повторний запуск не повинен дублювати записи (INSERT ... ON CONFLICT (email) DO NOTHING). І розрізняйте два рівні suppression: м'яке приховування (виключити з маркетингових кампаній, але лишити транзакційні листи) та повне suppress (не шлемо взагалі — для hard bounce і скарг). Людину, що просто втомилась від дайджесту, не варто відрізати від чека про оплату.
Не забудьте, що one-click unsubscribe тепер обов'язковий — і саме він знижує complaint rate, бо люди тиснуть його замість «Спам». У кожному bulk-листі:
Моніторинг після чистки: як зрозуміти, що спрацювало
Гігієна без вимірювання — це віра, а не інженерія. Зафіксуйте baseline до чистки й дивіться в три місця:
Google Postmaster Tools (postmaster.google.com) — Domain reputation (Bad/Low/Medium/High), графік Spam rate, IP reputation. Потрібен DNS TXT-запис для верифікації домену. Це головне джерело правди для Gmail.
Microsoft SNDS (sendersupport.olc.protection.outlook.com) — трафік RCPT-команд по IP, скарги, фільтрація для Outlook/Hotmail.
Свій сервер — rspamd web UI та rspamc stat, метрики Postfix за rejected/bounced.
Очікуваний ефект від дисциплінованої чистки: engagement rate росте, complaint rate падає протягом 2–4 тижнів. Важливе попередження: під час re-engagement ramp inbox placement може тимчасово провалитись — це нормально, ви ж свідомо шлете по ризикованому сегменту з нового субдомену. Не панікуйте й не задирайте частоту різко, щойно репутація відновилась: наростання обсягу після відновлення — окремий обережний процес, а не «повернемо все як було завтра».
Чекліст гігієни (копіпаст-готовий)
Double-opt-in увімкнено на всіх формах підписки.
Disposable-домени блокуються на формі (MX-lookup + словник), role-адреси реджектяться для маркетингу.
Hard bounce (5.x.x) → suppression автоматично, того ж дня.
Re-engagement шлеться з окремого subdomain із власним DKIM, батчами 50→200→1000.
Never-engaged сегментується окремо й suppress'иться агресивніше за всіх.
Suppression-таблиця перевіряється pre-send через LEFT JOIN — жоден лист не йде повз неї.
Ніколи DELETE FROM subscribers — тільки статус + reason + timestamp.
Погляд у Google Postmaster Tools щотижня, а не «коли вже впало».
Гігієна списку — це не подія в календарі, а стан вашої інфраструктури. Адреса не «видаляється» — вона переходить через active → lapsing → dormant → suppressed, і на кожному переході у вас є дані, щоб вирішувати за цифрами, а не за настроєм маркетингу. За порогів 2026 року іншого способу тримати домен у High reputation просто немає.