Knowledge base

How to turn a sending plan into hardware

EC2 instance sizing
Memory counts recipients, disk counts bytes

The manual gives a table of machine types from one cloud provider and honestly calls it an estimate: the result is shifted by configuration, hardware, the software set, the network and address reputation. The value lies not in the table but in the two rules below it — they are not tied to any provider.

Memory grows with the number of recipients — about 2 KB for each one waiting in the queue, regardless of message size. A hundred thousand recipients means about two hundred megabytes, however much the message itself weighs.

Space grows with volume — with the total size of the messages. The manual’s example: a hundred thousand recipients at 50 KB each require no less than six gigabytes of spool, and the actual need turns out slightly higher than the sum of the sizes. Accounting and logs are counted separately.

Hence the main consequence. These are two independent resources with independent reasons to grow. A node can be memory-bound with an empty disk — many recipients of light messages — or disk-bound with free memory — heavy messages to a small list. An estimate that treats them as one quantity is bound to be wrong about one of the two.

Throughput reference points, if needed: from four cores and 8 GB for two million 50 KB messages per hour up to sixteen cores and 32 GB for eight million.

The main trap is counting by the average and forgetting the queue. Memory is needed not for the messages sent in a day but for the recipients waiting at the same time. A receiver starts refusing, messages pile up, the bounce deadline is four days — and the queue grows to a volume nobody accounted for. A hundred thousand a day with calm sending fits into memory easily; the same hundred thousand stuck for four days is already four hundred thousand recipients at once.
What the Hub does. It checks a node before putting it into service and complains about what is obviously too small: less than a gigabyte of memory or less than ten gigabytes of disk is a rejection, less than two gigabytes of memory or forty gigabytes of disk is a warning. These are thresholds for “usable at all,” not a plan-based calculation.

The Hub could calculate for a plan, and it has enough data: it knows the node’s resources, and the planned volume and message size too. What is missing is the sending profile — in bursts or steadily, how deep the queue grows during refusals — and without it a plan-based calculation gives a number that is correct only for a calm day.

Recommended values

Count like this:

Resource Driven by How to estimate
memory recipients in the queue at the same time 2 KB per recipient plus headroom for the application itself
spool disk the total size of messages in the queue message size times the number of recipients, and a bit more
disk for accounting and logs sending volume counted separately, not part of the spool

The key word is “at the same time.” The number of recipients in the queue is determined not by daily volume but by how long messages live in it: the bounce deadline, the retry schedule and receiver behavior. A sensible estimate for the worst day is the daily volume multiplied by the bounce deadline in days.

Take headroom not in percent but in multiples. Both resources jump when a receiver has trouble, and that is exactly when the node should least of all be memory-bound.

The “volume times bounce deadline” estimate and the advice about headroom are ours. From the manual here come both constants, the example with a hundred thousand recipients at 50 KB, the caveat about accounting and logs and the throughput reference points.
Example configuration
# a plan-based estimate: 100,000 recipients a day, a 50 KB message
# memory:  100,000 × 2 KB              ≈ 200 MB  — with calm sending
#          × 4 (4-day bounce deadline) ≈ 800 MB  — when a receiver stalls# spool:   100,000 × 50 KB             ≈ 5 GB    — and a bit more in practice
# accounting and logs                   are counted separately
The highlighted line is the one people forget. The first line is true for a day when everything goes out right away; the second for a day when a large receiver held mail back — and that is exactly the day memory runs out.
yellow — — directive names, blue — blocks. They are highlighted the same way in the text of the card.
▲

Common mistakes and problems

what people get wrong and how it ends3 mistakes▶

Sizing memory by daily volume

§ 1.7.1.2

What it costsMemory is needed for recipients waiting at the same time, not those sent in a day. When a large receiver stalls, the queue lives as long as the bounce deadline, and the number of simultaneous recipients grows many times over.
How to spot itThe node works for months and becomes memory-bound exactly on the day a receiver has problems.
How to do it rightSize for the worst day: daily volume multiplied by the bounce deadline in days. Take headroom in multiples, not percent.

Treating memory and disk as one quantity

§ 1.7.1.2

What it costsThey grow for different reasons: memory follows the number of recipients, disk follows bytes. The “just get a bigger machine” estimate will be wrong about one of the two: light messages to a big list will eat memory while the disk is empty, heavy ones to a small list the other way around.
How to spot itOne resource is at its limit, while the other is only a few percent used.
How to do it rightCalculate them separately, with two rules. Monitor them the same way: watch the number of recipients in the queue and the spool size, not “node load.”

Sizing the spool without accounting and logs

§ 1.7.1.2

What it costsThe manual says to count them separately. Accounting grows with sending volume and on an active node catches up with the spool in size; when they share a partition, running out of space stops receiving messages.
How to spot itThe partition ran out of space, while the spool takes up only a small part of it.
How to do it rightPut the spool and accounting on different partitions, or plan space for both. Set up accounting rotation right away, not when space runs out.
Compatibility
PowerMTA 6.0
described in the manual of this version · platform: any
The vendor does not state the first version for every directive — there is no note here. The name also appears in the 5.0 edition of the manual.
Inheritance
An estimate has no inheritance — it is a calculation, not a setting. But directives affect both quantities: the bounce deadline and retry schedule decide how many recipients wait at the same time, and max-message-size caps what one recipient will take in the spool. The free space threshold (min-free-space) stops receiving when the disk does run low after all.
How to check on the node
Both resources are looked at together — separately, either of them looks calm:
pmta show status
df -h /var/spool/pmta && free -m
The first prints the number of recipients in the queue — this is the multiplier for memory. Then compare: recipients times 2 KB against free memory, spool size against free space. A node with one indicator at its limit and the other free is normal, not a sign of an error.
In the Hub
Cost of a mistake
safe: a wrong value breaks nothing
Scenarios
Capacity planning · Prepare a node for sending