Project: Mailing list handler
Short term:
1) Buy a subscription
Long term?
2) Replace with phplist
3) Replace with my own solution using Amazon SES
Here’s what your cPanel host is (very likely) doing, based on the screenshots/logs you shared and how Exim-based hosts watch for abuse—and how to keep your PHPlist sends under the radar.
How they detect “spam” at a high level
They aren’t “reading content.” They’re watching your mail behavior in the Exim logs and tripping rate/volume alarms.
-
Burst & sustain rate thresholds (time-window counters).
Your screenshots show triggers like:-
Level 1: 100 events in 600s (10 min) → 10/min average
-
Level 2: 200 events in 1800s (30 min) → 6.7/min average
-
Level 3: 250 events in 3600s (1 hour) → 4.2/min average
When you exceed these windows (per user), they flag you.
-
-
Source of mail = LOCALRELAY / cwdcheck.
-
LOCALRELAY = messages injected from a script on the server (e.g., PHP
mail()), not a remote SMTP client. -
cwdcheck = current working directory of the PHP process (helps them find bulk-senders/compromised scripts).
Lots of LOCALRELAY + high rate = classic “bulk sender” signature.
-
-
Subject repetition counters (logline:subject).
They also count identical subjects in short windows. Hundreds of the same subject in 10–30 minutes is a spam pattern. -
Bounce/error/invalid spikes.
High 550/551/552, many defers, or lots of @role addresses amplify suspicion. -
Auth/reputation failures.
SPF/DKIM/DMARC failures, new domain with no history, or your server IP edging onto blocklists. -
Abuse feedback loops / complaints.
If recipients hit “This is spam,” hosts tighten the screws quickly.
How to structure PHPlist so you don’t get flagged
1) Cap your rates below their tripwires
Design for the tightest window (the hour). The safe ceiling from your logs ≈ 4 emails/min sustained.
PHPlist settings (config.php):
-
batch_size = 40 -
batch_period = 600(40 emails every 600s = 10 min → 4/min average) -
throttle = 15(one email every 15 seconds = ~4/min)
That keeps you at ~240/hr, safely under the 250/hr Level-3 line and far below the 10-minute/30-minute triggers.
Rough runtime: 2,000 recipients ≈ ~8–9 hours at ~240/hr.
If your host has an account “max per hour” (common on cPanel), also set PHPlist’s “Maximum emails per hour” to 10–20% below that host limit.
2) Send as SMTP (authenticated), not PHP mail()
In PHPlist, set “Use SMTP” and send via:
-
Your cPanel SMTP (mail.yourdomain), or
-
A dedicated sender (SES/Mailgun/SendGrid)
SMTP-authenticated traffic looks better than big LOCALRELAY bursts, and you get clearer delivery errors.
3) Break campaigns into small waves
Instead of one monolithic send:
-
Segment 300–500 contacts per wave (industry, city, “warmth”), schedule waves hours apart.
-
Stagger start times if you have multiple lists.
-
Avoid synchronized spikes (e.g., not all at :00).
4) Reduce “bulk-signature” signals
-
Vary subjects slightly across waves (A/B two short variants).
(Doesn’t hide anything—just lowers the “identical subject” counters.) -
Personalize greeting or one line (name/company/city). Normal, human-looking mail.
-
From use one stable identity (your personal Gmail/Meteor for warm contacts, or your domain mailbox for cold—but don’t intermix the same audience in both in the same day).
5) Keep your list ultra-clean
-
Run through a verifier (NeverBounce/ZeroBounce/Bouncer etc.).
-
Remove role addresses (info@, support@…), noreply@, bounce@, and automations (@mailchimp, @aweber, @hubspot, craigslist relays, etc.).
-
Process bounces in PHPlist after each wave (set hard-bounce rules).
6) Pass all auth checks
-
SPF includes your sending host/service.
-
DKIM enabled for the sending domain.
-
DMARC at least
p=none; rua=...to watch failures.
7) Clear opt-out and reply handling
-
Real List-Unsubscribe header (PHPlist can add it).
-
Unsubscribe link visible.
-
Route replies to a monitored inbox; quick “remove me” handling lowers complaints.
8) Warm up & reputation
-
Start with your warmest segments first (past correspondents, recent interactions).
-
Keep daily totals modest the first week; expand only if bounce/complaints stay low.
Example: Safe plan for a 2,000-contact campaign (one day)
-
Configure rates (above).
-
Split into 5 waves × 400 contacts.
-
Schedule start times 8–10 hours apart or across two days if your host is strict.
-
Two subject lines (50/50 split).
-
Process bounces after each wave; suppress hard bounces immediately.
Quick checklist before you hit “Send”
-
SPF/DKIM/DMARC pass for your From: domain
-
PHPlist
batch_size/batch_period/throttleset = ~4/min -
Using SMTP auth (not PHP mail)
-
List cleaned & verified; role/system/automation emails removed
-
Unsubscribe visible + List-Unsubscribe header
-
Bounces configured & tested
-
Small A/B subject variants; light personalization
-
Segmented waves scheduled with gaps
Follow the above and you’ll stay comfortably under the host’s automated tripwires while looking like a normal, responsible sender.
Got it — let’s break this down beginner-style so you understand why you got banned and exactly what to do next time so it doesn’t happen again.
1. Why you got banned (in plain English)
When you sent your PHPlist campaign:
-
Too many emails went out too fast → Your host’s mail server saw an unusually high burst of messages from your account (hundreds in minutes). That’s a classic spam pattern.
-
The messages came from a web script (LOCALRELAY) → To the server, this looks exactly like a hacked WordPress sending spam or a bulk-mailer hammering out mail from PHP.
-
Lots of addresses were unknown, role-based, or from automated systems → This triggers bounces and spam traps, both of which hosts monitor.
-
Identical subject line to everyone → Another spam pattern that’s easy to detect.
-
Your domain/IP has little or no sending reputation → New sender + bulk send = red flag.
Hosts use automated “mail abuse monitors” that work like speed cameras — you tripped the limit, so they shut you down before their server got blocklisted.
2. Steps to check before you send again (PHPlist checklist)
Here’s the “don’t-get-banned” preflight list:
A. Make sure your list is safe to send to
-
✅ Permission-based — ideally, people who have emailed you or opted in, even loosely.
-
✅ List cleaned — run it through a verifier (NeverBounce, ZeroBounce, Bouncer).
Remove:-
Hard bounces (invalid emails)
-
Role addresses (info@, admin@, support@)
-
Obvious automations (noreply@…)
-
Spam traps (addresses you’ve never interacted with)
-
-
✅ Segment — don’t send to all 2,000 at once. Break it into smaller batches.
B. Make sure your sending setup is trusted
-
✅ SPF record includes your sending server/service.
-
✅ DKIM is enabled for your domain.
-
✅ DMARC is set (p=none at minimum).
-
✅ Use SMTP authentication in PHPlist, not PHP
mail()— this makes you look like a normal email program, not a spam bot.
C. Control your sending speed
-
✅ In PHPlist
config.php:$batch_size = 40 $batch_period = 600 # seconds (10 min) $throttle = 15 # seconds between messagesThis = max ~240/hour — slow enough to avoid tripwires.
-
✅ Stagger campaigns in waves — e.g., 500 contacts in the morning, 500 later.
D. Make your email look “human”
-
✅ Personalize at least the greeting (Hi John, …).
-
✅ Vary the subject line slightly between waves.
-
✅ Keep HTML clean & lightweight — avoid image-only messages.
-
✅ Always include a visible unsubscribe link.
E. Monitor after sending
-
✅ Watch bounce reports — remove hard bounces immediately.
-
✅ Track complaints (people clicking “spam”).
-
✅ If bounces > 2–3%, stop and clean again.
3. How to rebuild trust with your provider
Since they’ve warned you:
-
Start with your warmest segment (people you know).
-
Keep volume low for the first week — maybe 100–200/day.
-
Slowly ramp up if bounces are near zero and no complaints.
If you want, I can give you a “first safe send” plan for your next PHPlist email that’ll both warm up your domain and keep you 100% under the host’s radar. That way, you don’t risk a second ban.
Do you want me to make that for you?
Alright — here’s your Safe First Send Plan for PHPlist so you don’t get banned again.
PHPlist First-Send Safety Plan
Step 1 — Prep Your List (Day -2 to Day -1)
-
Verify emails: Run your 3,000 contacts through NeverBounce, Bouncer, or ZeroBounce.
Remove:-
Invalid addresses (hard bounces)
-
Role-based (info@, admin@, sales@, etc.)
-
Noreply/automated senders
-
Domains with no MX records
-
-
Segment into 5–6 groups of ~500 contacts.
-
Name them
Segment 1,Segment 2… so you can send in batches.
Step 2 — Configure PHPlist (Day 0)
Edit config.php so you don’t trip spam filters:
# Send 40 messages every 10 minutes
$batch_size = 40;
$batch_period = 600;
# Wait 15 seconds between each message
$throttle = 15;
# Stop sending on 5% bounces
$max_process_queue_time = 3600;
✅ Use SMTP with your Gmail/Google Workspace or approved SMTP relay (not PHP mail()).
✅ Make sure SPF, DKIM, and DMARC are set for your sending domain.
Step 3 — Warm Up & Send (Day 1–Day 6)
| Day | Segment | Emails to Send | Goal |
|---|---|---|---|
| 1 | Segment 1 | 100 | Start with your most engaged contacts |
| 2 | Segment 1 | 200 | Add more, still engaged/known people |
| 3 | Segment 2 | 300 | Mix new + warm contacts |
| 4 | Segment 3 | 400 | Larger batch, watch bounces |
| 5 | Segment 4 | 500 | Keep bounce rate <2% |
| 6 | Segment 5 | 500 | Final batch |
Rules during warm-up:
-
Wait 24 hours between sends so you can monitor complaints/bounces.
-
Stop sending to any address that bounces hard.
Step 4 — Craft the Email
Keep it short, plain-text style, personal-feeling:
Hi [First Name],
It’s been a while — hope you’re doing well.
Would you be open to a quick catch-up? Coffee if you’re nearby, or a short Zoom.
I’d love to hear what you’ve been up to and share a quick update on my end too.
Reply with a time that works best.
Best,
Saad Aziz
(503) 704-1506
P.S. Just got a new puppy, Loki.
✅ Include unsubscribe link at the bottom.
✅ Avoid links/images in the first warm-up email.
Step 5 — Watch the Results
-
Bounces: Remove hard bounces immediately.
-
Spam complaints: If >0.2%, stop and review content/list.
-
Engagement: Track replies — those are now hot leads.
Step 6 — If Someone Responds
-
Reply quickly — same day.
-
Offer to meet: coffee (if local) or Zoom.
-
Don’t sell — just reconnect, share updates, and listen.
If you follow this, you’ll stay under your provider’s radar while warming your list.
If you want, I can also add a progress bar + bounce log script to PHPlist so you can see exactly how your warm-up is going in real time. That would make it much easier to stop before trouble starts.
Do you want me to build that?
Here’s a practical Amazon SES warm-up playbook that works whether you’re doing cold outreach (with careful targeting) or sending to opt-in lists — it’s about building reputation gradually so you don’t trigger spam throttling like in your screenshot.
Amazon SES Warm-Up Plan
(Example: targeting 10,000 recipients over time)
Phase 1 – Week 1
-
Day 1: Send to 20–50 recipients only.
-
Day 2–3: Increase to 100–150 recipients.
-
Day 4–5: Increase to 200–250 recipients.
-
Goal: Keep bounce rate < 3%, complaint rate < 0.1%.
Tip: Use your most engaged / highest-quality contacts first so early sends get high open rates.
Phase 2 – Week 2
-
Day 6–7: Increase to 400–500 recipients.
-
Day 8–9: Increase to 750 recipients.
-
Day 10: Increase to 1,000 recipients.
Tip: Mix old and new recipients so engagement stays strong — don’t blast an untested cold list all at once.
Phase 3 – Week 3
-
Day 11–13: Send to 1,500–2,000 recipients/day.
-
Day 14–15: Send to 3,000/day.
-
Goal: By now, SES will usually trust your domain enough for higher volume.
Why This Works
-
Amazon SES tracks domain reputation, IP reputation, and recipient feedback.
-
A slow ramp-up:
-
Lets SES see low bounce/complaint rates before allowing higher sends.
-
Avoids sudden spikes that look like spammer behavior.
-
Builds a “healthy sender score” with inbox providers like Gmail, Outlook, Yahoo.
-
Extra Best Practices
-
Separate sending domain/subdomain
Example:mail.yourdomain.comfor cold outreach.
Keeps your main domain’s reputation clean. -
Authentication
Set SPF, DKIM, DMARC before first send. Without these, warm-up is useless. -
List hygiene
-
Use a verifier like NeverBounce or ZeroBounce before sending.
-
Remove invalid, role-based (info@, sales@), or risky emails.
-
-
Track engagement
If open rate drops below 20%, slow the ramp-up until it improves.
If you want, I can give you a day-by-day Amazon SES warm-up spreadsheet where you just plug in your target volume and it auto-generates the schedule so you don’t guess. That would keep you from tripping spam alarms like in your screenshot.
Comments
Post a Comment