> For the complete documentation index, see [llms.txt](https://docs.rumi.systems/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rumi.systems/rumi-core/guides/developing-applications/configuring-the-runtime/monitoring/per-transaction-statistics.md).

# Per-Transaction Statistics

Configure detailed transaction-level statistics collection for in-depth performance analysis.

{% hint style="warning" %}
**Performance Impact**: Users are advised to carefully test the performance impact of enabling per transaction stats particularly when operating under load, as collection and reporting of these stats can be quite costly in terms of CPU usage, disk write bandwidth, and disk space usage.
{% endhint %}

## Overview

Per-transaction stats provide detailed statistics for each transaction and message at the cost of greater overhead. Unlike aggregated engine statistics, per-transaction stats record timestamps and metrics for every transaction, allowing granular analysis of performance outliers and bottlenecks.

## Configuration

Per-transaction stats collection requires enabling both global latency collection and per-transaction capture:

```xml
<env>
  <nv>
    <!-- globally enable message latency stats -->
    <msg.latency.stats>true</msg.latency.stats>
    <!-- globally enable ODS store stats collection -->
    <ods.latency.stats>true</ods.latency.stats>
    <!-- Enable low level I/O timestamps-->
    <link.network.stampiots>true</link.network.stampiots>
  </nv>
</env>

<services>
  <service name="processor" mainClass="com.neeve.talon.starter.Application">
    <!-- Enable transaction latency stats collection -->
    <captureTransactionLatencyStats>true</captureTransactionLatencyStats>
    <!-- Capture transaction stats on a per transaction basis -->
    <capturePerTransactionStats>true</capturePerTransactionStats>
    <!-- Configure Per Transaction Stats Logger -->
    <perTransactionStatsLogging policy="UseDedicated">
      <flushOnCommit>true</flushOnCommit>
      <detachedWrite enabled="true">
        <queueOfferStrategy>SingleThreaded</queueOfferStrategy>
        <queueWaitStrategy>Blocking</queueWaitStrategy>
        <queueDrainerCpuAffinityMask>0</queueDrainerCpuAffinityMask>
      </detachedWrite>
    </perTransactionStatsLogging>
  </service>
</service>
```

With the above configuration, the application will create a `processor.txnstats.log` in the application's data directory. At the end of each transaction, an `AepMonTransactionStatsMessage` will be saved to this transaction log file which contains the captured stats for that transaction.

## Configuration Parameters

| Configuration Setting         | Description                                                                                                       |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `capturePerTransactionStats`  | Enables per-transaction statistics collection. Requires `captureTransactionLatencyStats` to also be enabled.      |
| `perTransactionStatsLogging`  | Configures the dedicated binary transaction log for per-transaction stats. Policy should be set to `UseDedicated` |
| `flushOnCommit`               | Whether to flush stats to disk after each transaction commit. Set to `true` for immediate persistence.            |
| `detachedWrite`               | Configures detached writing to offload I/O from the dispatcher thread. Should generally be enabled.               |
| `queueOfferStrategy`          | Strategy for offering messages to the detached write queue. Use `SingleThreaded` for single-threaded dispatchers. |
| `queueWaitStrategy`           | Wait strategy for the detached write disruptor. `Blocking` is appropriate for non-latency-critical logging.       |
| `queueDrainerCpuAffinityMask` | CPU affinity mask for the detached write thread.                                                                  |

## Prerequisites

Per-transaction stats collection requires the following global settings to be enabled:

* `nv.msg.latency.stats=true` - Enables message latency timestamps
* `nv.ods.latency.stats=true` - Enables store latency timestamps
* `nv.link.network.stampiots=true` - Enables low-level I/O timestamps
* `captureTransactionLatencyStats=true` - Enables transaction latency collection

## Performance Considerations

Per-transaction stats collection has significant performance impact:

* **CPU Usage**: Capturing and recording timestamps for every transaction
* **Disk I/O**: Writing stats for every transaction to disk
* **Disk Space**: Stats logs can grow rapidly under high transaction rates
* **Memory**: Buffering stats before writing

Always test the performance impact in a non-production environment before enabling in production.

## Related Topics

* [Per Transaction Stats](/rumi-core/guides/operating-applications/monitoring/per-transaction-statistics.md) - Working with per-transaction statistics logs at runtime
* [Engine Statistics](/rumi-core/guides/developing-applications/configuring-the-runtime/monitoring/engine-statistics.md) - Configure engine-level statistics collection
* [container Heartbeats](/rumi-core/guides/developing-applications/configuring-the-runtime/monitoring/xvm-heartbeats.md) - Configure container-level heartbeat emission
* [Transactions](/rumi-core/concepts/transactions.md) - Transaction concepts

## Next Steps

1. Understand the performance impact of per-transaction stats
2. Enable global latency stats collection
3. Configure per-transaction stats logging in DDL
4. Test performance under load in non-production environment
5. Use [TransactionStatsLogTool](/rumi-core/guides/operating-applications/monitoring/per-transaction-statistics.md#the-transactionstatslogtool) to analyze collected stats
6. Disable after collecting necessary data
