Knowledge base

records

<acct-file>criticalset by the Hub

Which record types go into this accounting file
in the configuration this is a linerecords d,binside the block <acct-file>
What the node will tell about itself at all

Accounting is the only channel through which the node tells what happened to messages. The line chooses what exactly it tells about. There are eight types, and each can be named by a letter or a word:

Letter Word What the record is about
d delivery the message was delivered
b bounce a local bounce generated by the node itself
t transient a transient error for one recipient
tq transient-queue a transient error for the whole queue
r receipt the message was accepted by the node for sending
f feedback-loop a complaint parsed by the processor
rb remote-bounce a bounce that arrived as a message from the receiving server
rs remote-status a status report from the receiving server

The default is d,b, and the line is written once per block.

A type that was not selected is an event that, for analytics, never happened. There is nothing to restore it from later: the node simply did not record it. So the set of types is, in essence, a description of what the fleet is able to measure at all.

Bounces come in two breeds, and this is the main subtlety of the set. b is bounces the node generated itself, synchronously, right in the conversation with the receiving server. Asynchronous bounces that arrive later as a message do not get in here — they have rb, and it works only with a configured bounce processor.

The vendor advises keeping t and tq in a separate file. One message can have many delivery attempts, and these records swell faster than the rest, cluttering the main file.

The main trap is assuming that b covers all bounces. It covers only synchronous ones. Hard bounces from large receiving servers often arrive as a separate message minutes or hours later, and without rb they will not be in accounting — which means they will not be in your deliverability statistics either.
What the Hub does. It writes it — and differently in its two accounting blocks.

In the telemetry block five types are selected: d, b, rb, t, feedback-loop. Asynchronous bounces (rb) and complaints are included on purpose: without them the share of hard bounces and spam complaints on the fleet dashboard would be incomplete. tq, r and rs are not included.

In the file block (/var/log/pmta/acct.csv) it is d, b, rb: deliveries and both kinds of bounces. The file is read by the “Accounting stats” module. Transient failures and complaints are deliberately not written there: attempts bloat the file, complaints have a different set of columns, and both go out via the webhook anyway.

Recommended values

The set is chosen by the questions you will need to answer:

Types What becomes visible
d,b (default) delivery and synchronous bounces
+rb the real share of hard bounces
+f spam complaints
+t,tq why messages are delayed — in a separate file
+r what was submitted to the node at all

rb and f work only with configured processors — without a bounce and complaint parsing block, records of these types will not appear.

The eight types, their full names, the d,b default, the “once per block” rule and the advice to move t and tq into a separate file come from the manual (§ 3.3.11.11). The analysis of our set is based on the Hub’s code.
Example configuration
# fleet telemetry: deliveries, both bounce types and complaints
<acct-file /var/log/pmta/mtahub-webhook.json>
    records d, b, rb, t, feedback-loop    record-fields d  *
</acct-file>

# transient errors — in a separate file, as the vendor advises
<acct-file /var/log/pmta/transient.csv>
    records t, tq
</acct-file>
In the second block the same events are written separately: one message has many delivery attempts, and in a shared file they crowd out everything else.
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▶

Treating type b as the complete set of bounces

§ 3.3.11.11

What it costsb includes only bounces generated by the node itself. Asynchronous ones — those the receiving server sends later as a message — go as type rb, and without it the hard bounce statistics are understated.
How to spot itThe bounce rate in accounting is noticeably lower than the mailbox providers’ dashboards show.
How to do it rightAdd rb and configure the bounce processor, otherwise records of this type will not appear.

Putting t and tq into the main accounting file

§ 3.3.11.11

What it costsOne message has many delivery attempts, and transient error records take up more space in the file than everything else combined. Parsing the main file becomes slow.
How to spot itThe accounting file grows faster than the sending volume.
How to do it rightMove t and tq into a separate accounting block — the vendor’s direct advice.

Adding a record type after the fact to look at the past

our experience

What it costsA type that was not selected was not written anywhere. There is nothing to restore past events from — they simply do not exist.
How to spot itAfter the edit, data appears only from that moment on.
How to do it rightChoose the set with a margin: an extra type costs disk space, while a missing one costs the ability to answer a question.
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.
Reference data
Syntax
records <type-list>
Values
a comma-separated list of d, b, t, tq, r, f, rb, rs — or their full names
Default
d,b § 3.3.11.11
Applying
reload, no restart needed
Queue
will not touch what is already queued
Where to write it
<acct-file>
How many times
once in the block
Everything here comes from the manual, with the section.
Inheritance
There is no inheritance: the line lives inside its <acct-file> and describes only its stream. There can be any number of accounting blocks, and different record types can be split across different files — which is exactly what the vendor advises doing with t and tq.
How to check on the node
The first column of every record is its type; that is how you check what gets into the file:
cut -d, -f1 /var/log/pmta/acct-*.csv | sort | uniq -c
For a JSON file the same is done by the type field. A missing expected type means either it is not selected here or there is no processor that produces it — this happens with rb, rs and f.
In the Hub
Value
The Hub picks it itself — pace, warm-up stage, metrics
Cost of a mistake
reversible: harms only while it is set
Scenarios
Bounce classification · Collect telemetry
Priority
critical