---
title: How to test email delivery end to end (and keep testing it)
description: Your mail server is up, the SMTP login works, SPF, DKIM and DMARC are in place, and the password-reset email still doesn't arrive. The only test that proves delivery is sending a real message and finding it in the mailbox. Here's how an email round-trip test works, what it measures (delivery time, Inbox or Spam, every relay hop), what a real result looks like and how to read it.
canonical: https://watchfor.io/blog/how-to-test-email-delivery
---

# How to test email delivery end to end (and keep testing it)

2026-10-05 · WatchFor Team · Email · email, deliverability, smtp, imap

Your mail server is up, the SMTP login works, SPF, DKIM and DMARC are in place, and the password-reset email still doesn't arrive. The only test that proves delivery is sending a real message and finding it in the mailbox. Here's how an email round-trip test works, what it measures (delivery time, Inbox or Spam, every relay hop), what a real result looks like and how to read it.

To **test email delivery** end to end, send a real message through your own
SMTP server and look for it in a mailbox over IMAP or POP3. Measure how long
it took to arrive, which folder it landed in, and what the receiving server
thought of it. Then delete it, and do it again in five minutes. That's an
**email round-trip test**, and it's the only kind of check that proves mail
actually arrives.

## Why "the server is up" isn't enough

Every piece of the mail path can look healthy on its own while the whole
thing fails:

- The SMTP server accepts the message (`250 OK`) and then **queues it** for
  hours because the next hop is rate-limiting it.
- The message arrives, but in **Spam**, because a DNS change broke DKIM
  signing.
- A new spam filter or relay in the middle **drops** mail with a certain
  attachment, link or sender.
- Delivery slows from two seconds to four minutes, and the one-time login
  code your app sends **expires before it arrives**.

A port check sees a green light in all four cases. An
[SMTP login check](/blog/smtp-monitoring-explained) does too. The customer
sees an email that never came.

This matters most for **transactional email**, the messages people are
actively waiting for: password resets, sign-up confirmations, one-time
codes, order confirmations, invoices. Nobody reports a missing newsletter;
everyone notices a missing reset link.

## How a round-trip test works

1. **Log in to the mailbox first** (IMAP or POP3). If that fails, don't send
   anything: there would be no way to find the message.
2. **Send a test message** through your SMTP server on 587 or 465, with the
   same kind of login your app uses. Note the moment the server accepts it.
3. **Look for it** in the Inbox every couple of seconds until it shows up or
   a timeout passes (two minutes is a sensible default). If it isn't in the
   Inbox, look in the spam folder too.
4. **Read the headers** of the message that arrived: the `Received` lines
   (every relay it passed and when), and the receiving server's
   `Authentication-Results` (SPF, DKIM and DMARC verdicts) and spam score.
5. **Delete it**, so a mailbox checked every five minutes doesn't fill up
   with test mail.

Two safeguards make this safe to run against a real mailbox. Each test
message carries a unique, signed token, so the test only ever finds and
deletes **its own** messages, never anyone else's mail. And it should never
be pointed at someone else's address: send to a mailbox you control.

## What a real round trip shows

Here's a WatchFor round-trip monitor sending through a real mail server and
reading the message back over IMAP every five minutes:

![Email round-trip monitor: delivered in about two seconds to the Inbox, the delivery path with each relay hop and whether it was encrypted, and the round-trip stages from mailbox login through SMTP TLS, login, send and delivery wait to deleting the test message](/blog/how-to-test-email-delivery-overview.webp)

How to read it:

- **Delivered in 2.0 s · Inbox.** The time is measured from the moment your
  SMTP server accepted the message to the moment it was found in the
  mailbox. A few seconds is normal for mail that stays on one provider;
  tens of seconds across providers; minutes means something is queuing it.
- **Delivery path.** Each relay hop from the `Received` headers, in order,
  with the delay it added and whether it was encrypted. Hand-offs inside one
  system (local or LMTP delivery) are marked *internal*. When delivery gets
  slow, this shows *where*.
- **Round-trip stages.** Connect, TLS and login on both sides, the send
  itself, the wait for delivery and the clean-up. Nearly all of the time is
  the delivery wait, which is what you want: the servers are fast, the mail
  is moving.
- **Authentication.** The SPF, DKIM and DMARC verdicts are taken from the
  receiving server's own `Authentication-Results` header. In this example
  the message never left the provider, so the server didn't write one and
  the card says so rather than guessing. Send to a mailbox at another
  provider and you get real verdicts.

The timing chart makes slow-downs visible long before mail is actually
lost:

![Round-trip timing chart: SMTP connect, TLS, login, send, delivery time and mailbox login over time, each leg as its own line](/blog/how-to-test-email-delivery-timing.webp)

## What to alert on

| Alert | Fires when | Why it matters |
| --- | --- | --- |
| **Message not delivered** | Sent, but not in the Inbox or spam folder within the timeout | Mail is being lost or held up badly |
| **Landed in spam** | Found in the spam folder instead of the Inbox | Usually authentication or reputation broke |
| **Slow delivery** | Delivery took longer than a threshold (a minute is a good start) | One-time codes and reset links expire |
| **SPF / DKIM / DMARC failed** | The receiving server's verdict isn't a pass | A DNS or signing change, often before spam placement follows |
| **Unencrypted relay hop** | A relay in the path didn't use TLS | Mail is crossing the internet in plain text |
| **Login or send failed** | The SMTP or mailbox side broke before delivery | The alert names the stage, so you know which side to fix |

## Doing it by hand

You can do one round trip yourself with `swaks`, a small SMTP test tool
available in most Linux distributions:

```bash
swaks --server mail.example.com:587 --tls \
  --auth-user test@example.com --auth-password 'your-password' \
  --from test@example.com --to test@example.com \
  --header "Subject: delivery test $(date +%s)"
```

Then open the mailbox, find the message, and choose **Show original** (Gmail)
or **View message source** (most other clients) to read the headers. The
`Received:` lines read bottom to top: the lowest one is where the message
entered, the top one is the final delivery. Our guide to
[reading email headers](/blog/how-to-read-email-headers) goes through a
real example line by line, and the free
[email header analyzer](/email-header-analyzer) does it for you.

Doing it once is a good diagnosis. Doing it every five minutes, with alerts,
is monitoring.

## Practical tips

- **Use a dedicated test mailbox**, ideally at the provider your customers
  use most. Sending to yourself on the same server proves your server works;
  sending to a Gmail or Outlook mailbox also tests the hand-off between
  providers and gives you their SPF, DKIM and DMARC verdicts.
- **Send through the same server and login as your app.** A test that uses a
  different route proves a different route.
- **Every five minutes is plenty.** Each check sends a real message, so
  there's no point going faster, and mailbox providers rate-limit logins.
- **Gmail and Microsoft 365 keep a copy of everything you send in Sent.**
  When your sending account is one of those, clean the Sent folder now and
  then, or use a mailbox where sent copies aren't saved automatically.

## How WatchFor tests email delivery

The [email round-trip monitor](/email-round-trip-monitoring) does all of
the above on your schedule: it logs in to the mailbox, sends a fixed test
message through your SMTP server, finds it over IMAP or POP3, reports the
delivery time, Inbox or Spam, the receiving server's verdicts and every hop,
and deletes it. Both passwords are stored encrypted for that one monitor
and never shown again. Settings and alert rules are in the
[round-trip docs](/docs/monitors/email-round-trip).

---

Canonical page: https://watchfor.io/blog/how-to-test-email-delivery · All articles: https://watchfor.io/blog/all.md · Site guide: https://watchfor.io/llms.txt
