Knowledge base

The telemetry contract

critical

<acct-file>
Everything the fleet can measure is described here

The <acct-file> block is the boundary between the engine and everything downstream, the Hub included. It answers five questions, and those answers have no other source.

Question Line
which events records — eight types
which fields record-fields, plus message headers via header_NAME
where to a path in the tag, a pipe or http-webhook-url
how files rotate move-to, move-interval, max-size, delete-after
what to hide privacy-policy

🔴 A field that was not selected cannot be recovered by any processing downstream. It produces not an error but emptiness — and that is the worst kind of loss: a silent one. In exactly the same way, a record type that was not selected is an event that never happened as far as analytics is concerned.

Hence the rule for the fleet: the field set on the nodes must be verified, not assumed. The receiver expects a certain composition, and nothing checks that the node is configured to write it.

Both lines understand negation — *,!field and !name — so the configuration can be written as “everything except” rather than as a list. This holds up noticeably better when new fields appear in later versions.

The main trap is thinking accounting can be tuned retroactively. Everything the block did not write is lost for good. Configure it with room to spare: an extra field costs disk space, a missing one costs the ability to answer a question nobody has asked yet.
What the Hub does. It writes two accounting blocks, and they mean different things.

Telemetry is a webhook to our address: five record types (d, b, rb, t, feedback-loop), each with the standard field set, deliveries and bounces also carrying the first-attempt time, the time in queue and the retry count, complaints the Feedback-ID header. One batch a minute, 1 MB ceiling. This is the source of every fleet dashboard.

Files on the node come from the block <acct-file /var/log/pmta/acct.csv>, and the engine appends the date to the name: acct-2026-09-15-0000.csv. They hold deliveries and both kinds of bounces (d, b, rb) with the same extra fields, a 25 MB ceiling and a one-week retention. The “Accounting statistics” module reads them.

The files are not moved: the move-interval 5m line, which silently did nothing without move-to, was removed on Aug 29, 2026. A new file starts with a new date in the name, and within a day when the size ceiling is reached.

Recommended values

The mechanism has no values of its own: the block’s lines set them.

What is configured With what Default
record types records d,b
fields record-fields all
format the extension in the path CSV, .json gives NDJSON
anonymization privacy-policy do not anonymize
retention delete-after 8 days

There can be several blocks, and that is the main technique: different questions, different files.

The eight record types, negation in both lines, the format depending on the extension and the interplay of the file rotation lines come from the manual (§ 3.3.11, § 12.1). The conclusion about irrecoverability and the rule to verify the field set across the fleet are ours.
Example configuration
# two accounting blocks: telemetry and a safety net — different questions, different files
<acct-file /var/log/pmta/mtahub-webhook.json>
    records d, b, rb, t, feedback-loop    record-fields d  *
    http-webhook-url https://hub.example.com/api/telemetry/pmta/7
    http-webhook-max-interval 1m
</acct-file>

<acct-file /var/log/pmta/acct.csv>
    max-size 25M
    delete-after 7d
</acct-file>
The second block has no record-type line — the d,b default applies. For a safety-net file that is enough; if statistics are built from the file, rb is added to it too.
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▶

Assuming the field set on the nodes instead of verifying it

our experience

What it costsThe receiver expects a certain composition, and the node is under no obligation to write it. A missing field produces emptiness downstream rather than an error, and it is discovered weeks later.
How to spot itAnalytics has the column, but not a single record from a particular node has values in it.
How to do it rightVerify the accounting file header on the nodes when they are added and after every configuration update.

Configuring accounting “for current needs”

our experience

What it costsQuestions about the data come later, and data for the past is not written retroactively. Every narrowing is a deferred inability to answer.
How to spot itA new question needs a field that is missing from the history.
How to do it rightTake everything (*) and narrow only for a measured reason — disk space or a requirement on the data composition.

Narrowing the stream by filtering in a single block

§ 3.3.11.5

What it costsThe filtered records end up nowhere. Unlike a narrow field set, whole events are lost here.
How to spot itEntire sending directions have disappeared from the statistics.
How to do it rightKeep a full block and do the filtering in a second one.
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 mechanism has no inheritance — the directives that switch it on inherit, and they all live inside their own block. Blocks know nothing about each other: the same event can end up in several files with different field sets and different degrees of anonymization.
How to check on the node
The main check across the fleet is not “is accounting being written” but “are the right fields in it.” Look at the file header:
head -1 "$(ls -t /var/log/pmta/acct-*.csv | head -1)"
The column set must be checked against what the receiver expects. A mismatch produces empty values downstream rather than an error — and the only way to notice it is exactly this, by looking at the file itself.
In the Hub
Cost of a mistake
reversible: harms only while it is set
Scenarios
Troubleshoot deliverability · Collect telemetry
Priority
critical