Knowledge base

What the submitting system assembles before sending

Connection, Message, Recipient
Three objects, and each setting belongs to one of them

The submission method is the same in all bindings: open a connection to the node, create a message, create recipients and attach them to the message, add headers and a body, hand it over for sending. Everything else in the chapter is a property of one of these three objects.

And the chapter is best read exactly that way. The object a setting belongs to tells you what it applies to: a message setting applies to all its recipients, a recipient setting to one person. The question “why did it turn out differently for one recipient” is almost always answered by the level at which the setting was set.

The manual is honest about the benefit. Bindings are not faster than a regular SMTP connection — except for merging, when there are several recipients per message. That is, they are chosen for personalization and control over an individual message, not for speed.

The transport is a modified SMTP, so submission can be local or remote; this makes no difference to the model.

The main point for those who do not use bindings: the same decisions are available over regular SMTP too — through the message’s control headers (control-headers). Knowing what the submitting system is entitled to decide is useful even if the bindings themselves are not needed.

The main trap is assuming submission is determined by the node’s configuration. The sending address, job ID, envelope ID, encoding, return type and per-recipient notifications are chosen by the submitting system, not by the settings file. The node’s setting defines the default and the boundaries; anything the submitting system named explicitly usually wins. Looking for the cause of one message’s odd behavior in the configuration when submission set it is the most common way to waste time.
What the Hub does. It does not use bindings — the warm-up sender submits messages over regular SMTP to the submission port, and so do the platforms the Hub is connected to.

But it does use control headers: X-Virtual-MTA with the sending address name is added to the message, and other headers when needed. This is exactly what this entry is about — the submitting side makes the decision, it is just expressed as a header rather than a binding call.

So the entry is useful to us as well: knowing what the submitting system is entitled to decide carries over from bindings to headers unchanged.

Recommended values

The model has no values of its own — it has levels at which a setting is set:

Level What it applies to Example decision
connection everything submitted through it which node and under which login
message all of the message’s recipients sending address, job, encoding
recipient one person merge variables, notifications

The selection rule is simple: the lower the level, the more expensive. A recipient setting means the message cannot be transmitted to everyone at once in one transfer. If there is no personalization, everything possible should be set at the message level.

The same is available over SMTP — via control headers, and with the same caution: a header left in the message will travel to the recipient. Headers that the node must not let out are removed by a submission block setting.

The level table and the “the lower, the more expensive” rule are ours. From the manual here come the assembly order, the composition of the three objects, the honest caveat about speed and the fact that the transport is a modified SMTP.
Example configuration
# the same decision two ways: via a binding and via a header
# binding: a message property
#   msg.setVirtualMTA("mta-news-1")
# regular SMTP: the same choice with a control header
X-Virtual-MTA: mta-news-1X-Job: campaign-4417
The Hub submits the second way. The highlighted line chooses the sending address for one message; the node will remove it before sending if the submission block is configured to do so — otherwise the header will travel to the recipient.
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▶

Choosing bindings for speed

§ 7

What it costsThe manual says it directly: bindings are not faster than a regular connection, except for merging with several recipients per message. The cost of a new dependency is repaid by personalization, not throughput.
How to spot itMoving to bindings did not change sending speed but added a library to the submitting system’s build.
How to do it rightStay on SMTP if personalization is not needed. Control headers provide the same decisions without a new dependency.

Setting at the recipient level what applies to the whole message

§ 7

What it costsA recipient setting prevents transmitting the message to everyone in one transfer: the body is sent again for each group. Costs grow for no benefit if the value is the same for everyone.
How to spot itThe volume of transmitted bytes is a multiple of the message size, while the number of recipients is ordinary.
How to do it rightMove the setting up to the message level wherever the value does not differ from person to person.

Looking for the cause in the configuration when submission made the decision

§ 7

What it costsThe sending address, job and encoding are chosen by the submitting system. Investigating one message’s odd behavior through the settings file leads nowhere: the file has the default, and the message did not follow it.
How to spot itOne message went out from the wrong address, even though everyone has the same configuration.
How to do it rightStart with accounting: it shows what was decided for the specific message. And check whether the submission block is allowed to obey headers.
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
The model has no inheritance — there is precedence: what the submitting system named wins over the configuration default. But the node sets the boundaries: the submission block decides whether the address selection header and the job header are to be obeyed at all. A forbidden header simply has no effect, and the message is accepted.
How to check on the node
What exactly submission decided is visible in accounting — both the sending address and the job are recorded there:
grep -m5 'campaign-4417' /var/log/pmta/acct*.csv
pmta show jobs
The accounting line has sending address and job fields — they show whether the node obeyed the headers or substituted the default. The second command shows the jobs the node knows: if a job is not on the list, the header was not accepted.
In the Hub
Cost of a mistake
safe: a wrong value breaks nothing
Scenarios
Connect a sending platform