Home / Alt manpages / smtp-source(1)

  • smtp-source(1)
  • User command
  • linux

Load-test a local SMTP listener with smtp-source

You will use Postfix's smtp-source to send repeatable test messages to a local SMTP or LMTP listener, first as a harmless single-message check and then with controlled concurrency. The examples target loopback addresses and reserved .test addresses, so they do not contact real mailboxes.

Before you start

Allow about 10 minutes for a basic test, plus time to inspect the listener's logs. You need the postfix package installed and a test SMTP service already listening. No root privileges are needed to run smtp-source itself. You may need elevated privileges to start or reconfigure the service that receives the test messages.

This guide describes the command installed here as Postfix 3.8.6-1ubuntu0.1. The program is explicitly an unsupported test utility, and its behaviour is not promised to remain compatible between Postfix releases. Check the installed manual page before copying these options to another host.

Safety boundary

Do not point a load test at an Internet-facing listener, a production relay, or a real recipient domain. smtp-source generates mail traffic; it can fill queues, consume disk and trigger rate limits. Start with one message, use loopback, and increase the load only while watching the receiver.

1. Confirm the installed command

Check the package version and the compact usage output. The usage line is useful when a distribution's build differs from the manual page you have read.

dpkg-query -W -f='${Package} ${Version}\n' postfix
smtp-source -v -m 1 -l 32 -f [email protected] -t [email protected] 127.0.0.1:2525

The second command will try to connect to port 2525 and will fail if no listener is there. That is expected at this checkpoint if you have not started one. A connection error proves only that the endpoint is unavailable; it does not test SMTP.

2. Run one harmless SMTP transaction

Use an SMTP test listener on loopback. Port 2525 is a common unprivileged choice, but use the port your listener actually provides. The following sends one message with a 128-byte payload, a clear sender and recipient, and a subject for log searches.

smtp-source -v -c -m 1 -l 128 \
  -M test-client.example.test \
  -f [email protected] \
  -t [email protected] \
  -S 'smtp-source smoke test' \
  127.0.0.1:2525

-v prints protocol debugging, while -c displays a counter each time the DATA command completes. The default is one message, one recipient and one SMTP session, so the explicit values make the test easier to recognise.

Checkpoint

A successful run reaches the receiver and increments the DATA counter. Confirm the receiver's log or capture output contains one accepted transaction for [email protected]. If the command reports connection refused, check the listener address and port. If it reports an unexpected SMTP reply, remove -A while diagnosing so the command stops at the first protocol error.

3. Make the payload predictable

Without -F, smtp-source creates the message content itself. Use -l to set the payload length; headers are not included in that length. This is convenient for throughput tests where the size, rather than the text, matters.

smtp-source -c -m 5 -l 4096 -f [email protected] \
  -t [email protected] 127.0.0.1:2525

Use -F when the test needs a known header and body. The file is treated as a pre-formatted message header and body. The program adds CRLF line endings and dot-stuffs lines that begin with a dot, so keep the file as ordinary text rather than pre-encoding SMTP commands.

cat > /tmp/smtp-source-message.txt <<'EOF'
From: [email protected]
To: [email protected]
Subject: fixed smtp-source payload

This body is used only by the local test listener.
EOF
smtp-source -c -m 1 -F /tmp/smtp-source-message.txt \
  -f [email protected] -t [email protected] 127.0.0.1:2525

The temporary file is safe to remove after the test with rm -- /tmp/smtp-source-message.txt. Do not place credentials or personal mail in it.

4. Add recipients and parallel sessions gradually

-r sets the number of recipients per transaction. -s runs that many SMTP sessions in parallel. These are separate controls: five sessions with two recipients each can create ten recipient deliveries per wave.

smtp-source -v -c -m 20 -l 1024 -r 2 -s 4 \
  -M test-client.example.test \
  -f [email protected] -t [email protected] \
  127.0.0.1:2525

With -N, the program adds a non-repeating sequence number to each recipient address. Put an explicit delimiter at the end of the local part, as in [email protected], if the receiver uses plus addressing. This avoids making every request look like a cache hit, but your test receiver must accept those generated addresses.

Increase only one variable at a time. Watch CPU, memory, open connections, queue depth, listener logs and disk space. Keep the message count small until the receiver's response time and error rate are understood.

5. Control pacing and connection reuse

Use -w for a fixed delay between messages or -R for a random delay from zero up to the supplied interval. The delay applies independently to delivery threads, so it is not a global rate limiter when -s is greater than one.

smtp-source -c -m 30 -l 512 -s 2 -w 1 \
  -f [email protected] -t [email protected] 127.0.0.1:2525

By default, a message is sent in its own connection. Add -d to keep a connection open and send the next message over it. This tests a different receiver path from repeatedly opening sessions. The utility does not support SMTP command pipelining, so it is not a complete model of every mail client.

6. Test LMTP or a UNIX socket

For LMTP, add -L and use the listener's TCP endpoint or UNIX-domain socket. For a socket, the endpoint must begin with unix:.

smtp-source -L -v -c -m 1 -l 256 \
  -f [email protected] -t [email protected] \
  unix:/run/example-lmtp.sock

Use the exact socket path from the service configuration. A missing socket, wrong permissions or a service that speaks SMTP rather than LMTP will fail before a useful message test completes. Do not change socket ownership or service configuration just to make this command work; fix the test setup and undo any temporary setup afterwards.

Common traps

  • The default port is SMTP port 25, not the test port 2525. Always write the port explicitly for a local test.
  • The default sender and recipient are generated from the machine hostname. Set -f and -t so logs and receiver policy are unambiguous.
  • -o is old mode: it omits HELO and message headers. It is useful only when deliberately testing an old or unusual receiver path.
  • -A continues after an unexpected positive-reply mismatch. It can help measure a deliberately faulty endpoint, but it can also hide the first protocol failure.
  • -T changes the TCP window size and accepts values greater than zero and less than 65536. Use it only to investigate a suspected TCP window-scaling problem.

Done means

  • You confirmed the installed Postfix version and command syntax.
  • One local transaction completed and was visible in the receiver's logs.
  • You chose message size, count, recipient count and sessions deliberately.
  • You monitored the receiver while increasing traffic and stopped before queues or disks filled.
  • You removed temporary test files and restored any temporary listener setup.