Contents
- Why the accounting log is foundational
- What the accounting log is
- The CSV format and the acct-file block
- The record types and the records directive
- The key fields
- Customizing the logged fields
- The foundation of analytics and suppression
- Log rotation and management
- When the accounting log is missing data
Why the accounting log is foundational
Almost everything an operator knows about what PowerMTA is actually doing, the delivery rate, the bounce rate, the deferral patterns, the per-ISP behavior, comes from one place: the accounting log. And the bounce processing that feeds suppression reads from it too. The accounting log is the data foundation of a PowerMTA operation, and an operator who understands its format and configures it well has the data they need; an operator who treats it as an afterthought finds, when they need to analyze something, that the data was not captured.
This guide exists to explain the accounting log format and fields thoroughly. The structure of this guide: why the accounting log is foundational, what the accounting log is, the CSV format and how the acct-file block configures it, the record types and the records directive, the key fields each record carries, customizing which fields are logged, why the accounting log is the foundation of analytics and suppression, log rotation, and the diagnostic workflow when the accounting log is not capturing what is needed.
What the accounting log is
The PowerMTA accounting log is the structured record PowerMTA writes of every mail event it handles.
Every time PowerMTA processes a message, a successful delivery, a bounce, a transient failure, a message received for sending, PowerMTA writes a record of that event to the accounting log. Each record captures the relevant details: the recipient address, the receiving domain, the SMTP response, the diagnostic text, the bounce category where applicable, the source IP, timestamps, and other fields.
The accounting log is, in effect, the complete history of PowerMTA's sending activity, in a structured, parseable form. It is the foundation of nearly everything an operator does to understand and act on their sending:
- The delivery rate, the bounce rate, the per-ISP behavior, the deferral patterns, all come from analyzing the accounting log.
- The bounce processing and suppression pipeline reads the bounce records from the accounting log to feed the suppression list.
- Monitoring of delivery health draws on the accounting log's data.
Because the accounting log is the source from which the operator's analytics, monitoring, and suppression are all built, getting its configuration right, capturing the records and fields the downstream uses need, is foundational to operating a PowerMTA deployment well.
The CSV format and the acct-file block
The accounting log is conventionally written as a CSV file, comma-separated values, a plain-text tabular format where each line is a record and the fields are separated by commas.
The CSV format is a deliberate choice: it is simple, universally parseable, and easy for any analytics tool, database import, or script to consume. An operator's downstream tooling can read the accounting CSV with standard CSV handling.
The accounting log is configured through an acct-file block in the PowerMTA configuration:
<acct-file /var/log/pmta/accounting.csv>
records d,b,t,rb,f
move-interval 1h
</acct-file>
The acct-file block's tag specifies the file path the accounting log is written to. Inside the block, directives configure the log: the records directive lists which record types to capture, and other directives control aspects like the file's rotation.
A PowerMTA configuration can have more than one acct-file block, defining multiple accounting files, which lets an operator, for instance, write different record types to different files, or write a separate accounting file for a particular purpose. The common case is a single accounting file capturing the needed record types, but the multiple-file capability exists for operators who want to organize the accounting output.
The acct-file block is where the operator controls what the accounting log captures and where it goes, and configuring it deliberately, rather than accepting whatever the default provides, is the starting point for a useful accounting log.
The record types and the records directive
The accounting log captures several record types, each representing a different kind of mail event. Which types are captured is controlled by the records directive.
| Record type | Code | Event |
|---|---|---|
| Delivery | d | A message successfully delivered |
| Bounce | b | A delivery attempt that permanently failed |
| Transient failure | t | A delivery attempt that temporarily failed (a deferral) |
| Received | r / rb | A message accepted by PowerMTA for sending |
| Other | various | Additional event types |
Each record type is identified by a short letter code, and the records directive on the acct-file block lists the codes of the types to capture, as in the records d,b,t,rb,f example earlier.
The choice of record types matters because the downstream uses depend on having the right records:
- For bounce processing and suppression, the bounce records (b) must be captured.
- For deliverability analysis, the delivery records (d) and the transient failure records (t), which show the deferrals, are needed.
- For a view of inflow, the received records capture what entered PowerMTA.
For a complete picture, capturing the delivery, bounce, and transient failure records at minimum is typical, with the received records adding the inflow view.
The transient failure records, the t records, are sometimes left out of an accounting configuration, and that is a mistake. The transient failure records are how an operator sees the deferral patterns, the 421 throttling from receivers, the temporary failures that precede a real problem. A rising rate of transient failures from a receiver is an early warning of a deliverability issue, and that warning is only visible if the t records are being captured. An accounting configuration that logs deliveries and bounces but omits transient failures misses the deferral data entirely, which blinds the operator to one of the most useful early signals. Capture the transient failure records.
An operator configuring the accounting log should choose the record types deliberately, based on what the analytics, monitoring, and suppression need, rather than leaving it to a default that might omit something important.
The key fields
Each accounting record is a row of fields, and understanding the key fields is what lets an operator read and analyze the accounting log.
The important fields an accounting record can carry:
| Field | What it holds |
|---|---|
| Record type | The type code: d, b, t, and so on |
| Timestamp | When the event occurred |
| Recipient | The recipient email address |
| Receiving domain | The destination domain |
| Source IP | The IP the mail was sent from |
| Virtual MTA | The VMTA used |
| SMTP / DSN status | The response code from the receiver |
| Diagnostic text | The receiver's diagnostic message |
| Bounce category | The category PowerMTA assigned (for bounces) |
| Message size | The size of the message |
These fields together describe each event fully. The record type says what kind of event it was. The timestamp places it in time. The recipient and receiving domain say who the mail was for. The source IP and virtual MTA say how it was sent. The SMTP status and diagnostic text say how the receiver responded, which is the heart of a deliverability analysis. The bounce category, on bounce records, says how PowerMTA categorized the failure, which drives suppression.
An operator analyzing the accounting log works with these fields: grouping by receiving domain to see per-ISP behavior, filtering by record type to separate deliveries from bounces from deferrals, reading the SMTP status and diagnostic text to understand failures, and using the bounce category to drive suppression logic. Knowing what each field holds is the literacy that makes the accounting log usable.
Customizing the logged fields
The accounting log's fields can be customized, the operator can configure which fields each record includes, through the acct-file block.
PowerMTA's accounting records can carry a wide range of fields, the ones above and others, and the operator can configure the field list so the accounting log captures exactly the fields needed.
Particularly useful is the custom-field capability: PowerMTA can be configured to log values from the message's own headers into the accounting record. An operator who includes an identifying header in their mail, a campaign identifier, an encoded recipient reference, an X-Job header, can have that value captured in the accounting log.
The value of this is significant. With a campaign identifier logged, the operator can analyze the accounting log per campaign, the delivery rate of campaign A versus campaign B, the bounce rate of a particular send. With a recipient reference logged, an accounting record can be tied back to a specific recipient in the operator's own systems. The custom fields turn the accounting log from a record of generic mail events into a record that connects to the operator's own campaign and recipient data.
The principle for the field configuration: capture exactly the fields the downstream uses need, no more and no less. Capturing fields that nothing uses just makes the log larger. Failing to capture a field that an analytics or suppression process needs means that process cannot do its job. So the field list should be driven by the requirements of the analytics, monitoring, and suppression that consume the accounting log. An operator setting up the accounting log decides the record types and the fields together, designing the accounting log to be the data source their tooling actually needs.
The foundation of analytics and suppression
The reason the accounting log configuration matters so much is that the accounting log is the foundation everything downstream is built on.
The downstream uses of the accounting log:
Deliverability analytics. The delivery rate, bounce rate, deferral rate, the per-ISP breakdown, the trends, all are computed by analyzing the accounting log. An operator's understanding of how their sending is performing comes from accounting log analysis.
The suppression pipeline. The bounce processing that feeds the suppression list reads the bounce records from the accounting log. The accounting log is where the bounces are captured, and the suppression pipeline ingests them from there.
Monitoring. Monitoring of delivery health, the bounce rate trending up, the deferral rate climbing, draws on the accounting log's data.
Reputation and incident diagnosis. When something goes wrong, the accounting log is the primary diagnostic source, the SMTP responses and diagnostic text in the records are how the operator sees what receivers are doing.
The practical implication is that the accounting log must capture what these downstream uses need. The common pattern for using the accounting log at scale is to ingest it into a database or analytics system, the CSV records loaded into a queryable store, where the operator can run the analyses. The accounting log is the raw data; the analytics system is where it becomes insight.
And this is why a deliberate accounting configuration matters: if the accounting log does not capture a record type or a field that a downstream use needs, that use is crippled, and the gap is often discovered only when the operator tries to do the analysis and finds the data was never there. The accounting log should be configured at the start to capture everything the operator's analytics, suppression, and monitoring will need.
Log rotation and management
The accounting log grows continuously, every mail event adds a record, and a high-volume PowerMTA deployment generates a large accounting log. This needs management.
PowerMTA's accounting supports rotation: rather than writing forever to one ever-growing file, the accounting log is rotated, periodically closed off and a new file started, so the accounting data is in a series of files covering successive periods. The acct-file block's configuration controls the rotation, with a directive setting the rotation interval, so the operator can have, for instance, a new accounting file each hour or each day.
The rotation interval interacts with the downstream ingestion: a common pattern is to rotate the accounting file on an interval and have the ingestion process pick up each completed file and load it into the analytics store. PowerMTA's accounting can move a completed file to a location where the ingestion process collects it, which is a clean handoff, PowerMTA finishes a file, the ingestion takes it.
Beyond rotation, the operator manages the accounting log files: the older files, once ingested into the analytics store, can be archived or removed according to a retention policy, so the disk does not fill with accounting files indefinitely. A high-volume deployment's accounting log is a meaningful amount of data, and the rotation plus a retention policy keeps it managed.
The accounting log management, rotation, ingestion, retention, should be set up as part of establishing the accounting log, alongside choosing the record types and fields. An unmanaged accounting log that grows without rotation eventually becomes a single huge file and, on a busy server, a disk-space problem.
When the accounting log is missing data
When the accounting log is not capturing what an operator needs, the diagnostic workflow:
Step 1: identify what is missing. Determine specifically what data is absent, a record type not appearing, a field not present, the log not being written at all.
Step 2: for a missing record type, check the records directive. If a record type is not appearing, deliveries, bounces, or transient failures missing, check the records directive on the acct-file block. The type's code must be in the list. A common gap is the transient failure records (t) being omitted.
Step 3: for a missing field, check the field configuration. If a field is absent from the records, check the acct-file block's field configuration. The field must be included in the configured field list. For a custom header field, confirm both that the field is configured and that the mail actually carries the header.
Step 4: for the log not being written, check the acct-file block and path. If the accounting log is not being written at all, confirm the acct-file block exists, the file path is correct and writable, and PowerMTA has permission to write there.
Step 5: confirm the configuration was reloaded. If the accounting configuration was changed, confirm PowerMTA was reloaded so the change took effect.
Step 6: check rotation and ingestion. If the accounting data seems to be captured but the downstream analytics are missing it, the issue may be in the rotation or ingestion, the ingestion process reading the wrong path, or not picking up the rotated files. Confirm the rotation and the ingestion handoff are working.
Step 7: verify with a test. After a fix, generate some mail events and confirm the accounting log captures them with the expected record types and fields.
An operator we worked with wanted to investigate a deliverability concern: they suspected a particular receiver had been throttling their mail, and they wanted to analyze the pattern of deferrals over the preceding weeks to understand when it started and how it had developed. They went to their accounting data, which they ingested into an analytics database, to run the analysis, and found they could not do it. The analysis they wanted needed the transient failure records, the deferrals, the 421 throttling responses, because that is what a throttling pattern is made of. But their accounting log had never captured the transient failure records. When they had originally set up their PowerMTA accounting, they had configured the records directive to capture deliveries and bounces, the d and b records, reasoning that deliveries and bounces were the important outcomes, a message either got delivered or it bounced. They had not included the t records, the transient failures, perhaps not realizing how important the deferral data would turn out to be. So for the entire history, their accounting log had recorded every delivery and every bounce, but no deferrals at all. The deferral pattern they now wanted to analyze had simply never been captured, the data did not exist. They could see, from the delivery records, that delivery to the receiver had been lower than expected, but they could not see the deferrals that would have shown the throttling developing, because those events had been processed by PowerMTA and, with the t records not in the records directive, never written to the accounting log. The fix going forward was immediate, add t to the records directive so transient failures would be captured from then on, but it could not recover the past data. The weeks of deferral history they wanted to analyze were gone, never recorded. The lesson is that the accounting log captures only what it is configured to capture, and the configuration decision is made before the data exists, not after. The transient failure records are exactly the kind of data that seems less essential than deliveries and bounces until the day an operator needs to analyze a throttling pattern, at which point their absence makes the analysis impossible. The accounting log should be configured at the start to capture everything the operator might need, the delivery, bounce, and transient failure records at minimum, because a record type omitted from the configuration is data that is lost forever, and the realization that a record type was needed almost always comes after the period that needed analyzing has already passed.
The PowerMTA accounting log is the structured record of every mail event PowerMTA handles, and it is the foundation that the operator's deliverability analytics, suppression pipeline, monitoring, and incident diagnosis are all built on. It is conventionally a CSV file, configured through an acct-file block that specifies the path, the record types via the records directive, and the fields. The record types, delivery, bounce, transient failure, received, and others, should be chosen deliberately, with the transient failure records in particular not omitted because they carry the deferral data that is an early warning of deliverability problems. The fields can be customized, including custom fields that log values from the message's own headers, which lets the accounting log connect to the operator's campaign and recipient data. The accounting log feeds everything downstream, so it must be configured to capture what those downstream uses need, and it must be managed with rotation and a retention policy because it grows continuously. Operators who configure the accounting log deliberately at the start, capturing the record types and fields their analytics and suppression will need, have the data foundation their operation requires; operators who accept a partial default, as the case shows, discover too late that a record type they did not capture is data lost forever.