← Back to all topics

Email warmup

Gradually send low-volume mail to seed inboxes, raise daily limits over time, and monitor delivery from the Email Warmup page.

Who this is for: Users warming a new or cold sending domain before full campaign volume.

Before you start

Email Warmup sends real messages through your brand SMTP to seed inboxes you control.

Prerequisites:
1. Register your domain under Setup domain, verify DNS, and activate it.
2. Configure SMTP for the brand (Settings) so MailStalk can send.
3. Add seed inboxes — warmup only sends to addresses in your seed list.
4. Create a warmup profile for the domain, then click Start (play) to activate it.

A background cron job must run on the server (warmup_module/cron_warmup.php). Without cron, profiles stay idle and logs stay empty.

Email Warmup page layout

The page has four main blocks:

Warmup Profiles — create and manage sending schedules per domain.
Seed Inboxes — add, import, enable, or remove recipient addresses.
Warmup Message Template — optional custom subject/body for all warmup sends.
Recent Warmup Logs — history of each send attempt with status.

Success and error banners appear at the top after saves or CSV imports.

Create a warmup profile

Click Add Profile to open the form. Profile type is Domain warmup (domain-based reputation).

Fields and rules:

Domain — pick an active, verified domain from Setup domain. Required.

Minimum delay after each email (seconds) — random pause between sends in a batch. Range 10–3600; recommended 60–300. Default in the form is 120.

From name — sender display name. Letters and spaces only.

From email — must be an address on a verified active domain (domain username @ domain).

Start date — day the ramp-up schedule begins (used to calculate today’s limit).

Start daily — emails on day one of the schedule. Maximum 15 when saving.

Increase/day — added to the daily cap each calendar day after start date. Maximum 10.

Max/day — ceiling for daily sends. Maximum 200.

Schedule days — which weekdays warmup may run. Use numbers 0–6 comma-separated (0=Sunday, 1=Monday … 6=Saturday). Example: 1,2,3,4,5 for weekdays only.

Send window start / end — time of day warmup may send (24-hour). Supports overnight windows (e.g. 22:00–02:00).

Click Save Profile. New profiles are created Inactive — use the play button in the table to start warmup.

  1. Open Email Warmup from the sidebar.
  2. Click Add Profile and select your verified domain.
  3. Set from name, from email, start date, and ramp limits (start daily, increase/day, max/day).
  4. Set schedule days and send window times.
  5. Save, then click Start on the profile row to activate.

How daily limits work

Today’s send cap is calculated from the profile:

daily_limit = min(Max/day, Start daily + Increase/day × days since start date)

Example: Start daily 10, Increase/day 5, Max/day 200, start date 7 days ago → limit = min(200, 10 + 5×7) = 45 emails today.

The profile table shows Today: sent/limit (e.g. 3/45). The counter resets at midnight when the cron runs on a new calendar day.

Additional system limits:
• Each seed inbox receives at most 1 warmup email per day.
• Each cron run sends at most 20 emails per active profile.
• Sends only happen inside the profile’s schedule days and send window (server timezone Asia/Dhaka).

Manage profiles

Profiles table columns:

Type — Domain and the domain name.

From — from name and from email.

Schedule — schedule days, send window, and today’s sent/limit.

Status — Active (green) or Inactive (paused).

Actions — Start/Stop toggles is_active; Delete removes the profile.

If your plan expires, active profiles for that brand are automatically deactivated by the cron job.

Seed inboxes

Seeds are the only addresses warmup will mail. Mail is never sent to your main subscriber lists from this feature.

Add one seed — click Add Seed, enter email (required) and name (optional), Save Seed.

Enable / disable — toggle per row without deleting.

Delete — remove one seed, or Delete All Seeds to clear the list.

Pagination — 10 seeds per page (seed_page in the URL).

Duplicate email — adding the same address again reactivates it and updates the name if provided.

Import seeds from CSV

Use Import seeds from CSV in the Seed Inboxes card.

File format:
• CSV with comma-separated values.
• Column 1: email (required).
• Column 2: name (optional).
• First row may be a header — rows where column 1 is email or email_address are skipped.

Example file:
email,name
friend@gmail.com,Alex
partner@outlook.com,
colleague@gmail.com,Jamie

Rules on import:
• Invalid email formats are skipped.
• Valid rows are inserted; duplicates update name and set active.
• After import you see a summary such as Imported: 12, Skipped: 2.
• Accepts .csv files only.

  1. Prepare a CSV with email in column 1 and optional name in column 2.
  2. Click Choose file and select the CSV.
  3. Click Import CSV.
  4. Review the success or error banner for imported/skipped counts.

Warmup message template (base template)

The Warmup Message Template card controls what subscribers see in seed inboxes.

Custom template — enter Subject (max 255 characters) and Message body in the HTML editor (CKEditor). Both must be filled to save. Click Save Template.

Default pool — if you leave subject and body empty, or click Use Default Pool, MailStalk deletes your saved template and picks a random short message from the built-in pool on each send.

Default pool examples (subject lines):
• Quick question
• Following up
• Checking in
• One more thing

Each default message is plain, human-style text (short follow-up tone). Only one custom template is stored per brand; it overrides the pool until you reset to defaults.

Sending order: cron checks warmup_message_templates for your brand → if subject and body exist, uses them for every warmup email → otherwise random entry from the default pool.

How sending works (behind the scenes)

1. Cron loads all Active profiles.
2. For each profile: checks plan active, schedule day, and send window.
3. Computes remaining sends today vs daily limit and available seeds (1 per seed/day).
4. Picks eligible seed addresses at random.
5. Picks message (your template or default pool).
6. Queues send jobs (RabbitMQ) and writes warmup_logs rows.
7. Worker sends via your brand SMTP (PHPMailer) with a random delay between messages in a batch.

Log statuses you may see:
• sent — delivered successfully.
• failed — SMTP or queue error.
• queued — job waiting for worker.
• skipped — not counted toward daily limit in some edge cases.

Warmup uses the same SMTP host, port, SSL/TLS, and credentials as your brand Settings.

Recent Warmup Logs

The log table at the bottom of the page shows send history for your brand.

Columns:
• Sent at — date and time of the log entry.
• Profile — domain tied to the warmup profile.
• To — seed email address.
• Subject — subject line used.
• Status — sent (green), failed (red), or other states.

Pagination — 20 entries per page (log_page URL parameter). Newest first.

If logs are empty: confirm the profile is Active, seeds exist and are active, cron is running, current time is inside the send window, and today’s limit is not already reached.

Common questions

Profile saved but nothing sends.

Click Start on the profile — new profiles are Inactive. Also add active seeds, stay inside schedule/window, and ensure server cron runs.

Why only 1 email per seed per day?

This is intentional to mimic natural sending and avoid hammering the same inbox.

Can I use my campaign list as seeds?

Only addresses in Seed Inboxes receive warmup mail. Import or add them explicitly; do not expect automatic sends to list subscribers.

What if I clear the message template?

Use Default Pool or save with empty subject and body — the system rotates through built-in short messages.

CSV import skipped rows.

Check email format, remove bad lines, and ensure column 1 is the address. Header row email/email_address is auto-skipped.

What does Today 5/45 mean?

5 warmup emails sent today for that profile; 45 is today’s calculated daily limit from your ramp settings.