← Operator library Access & AAA

Build RADIUS Accounting You Can Reconcile

How to turn Start, Interim and Stop packets into reliable session evidence without mistaking counters for a financial ledger.

What this note covers

How to turn Start, Interim and Stop packets into reliable session evidence without mistaking counters for a financial ledger.

Accounting is an event stream

RADIUS accounting does not deliver a perfect session row. It delivers events that must be correlated: a Start announces a session, Interim-Updates advance its counters, and a Stop describes its end. Packets may be delayed, repeated or missing when a router, database or management path fails.

The collector therefore needs two things at once: an immutable record of what arrived and a current projection that operators can query quickly. Keeping only the latest row makes troubleshooting difficult; keeping only raw packets makes dashboards expensive and ambiguous.

Packet state Expected effect Do not assume
Start Create or identify an open session. That no earlier session exists for the username.
Interim-Update Advance time, octets and current NAS context. That every previous update arrived.
Stop Close the matching accounting session. That the Stop will always be delivered.
Accounting-On/Off Mark a NAS accounting lifecycle change. That every open session survived a router restart.

Choose a composite session identity

A username is not a session key. The same subscriber may reconnect quickly, connect through another NAS, or be permitted concurrent sessions. Acct-Session-Id is central, but its uniqueness is scoped by device implementation. Store it with an unambiguous NAS identity and the session start context.

Minimum correlation key: normalized NAS identity plus Acct-Session-Id. Preserve username, framed address, calling station and access port as searchable context rather than using any one of them as the primary key.

Make duplicate packets harmless

UDP delivery and retry behaviour mean the collector can receive the same logical update more than once. Processing must be idempotent. A repeated Interim-Update should not double usage, and a repeated Stop should not create a second closed session.

  1. Authenticate the NAS. Reject requests from unknown clients or invalid authenticators.
  2. Store receipt context. Capture receive time, source and a packet fingerprint suitable for diagnostics.
  3. Resolve the session. Use the composite identity, never the newest row for a username.
  4. Apply monotonic fields. Accept counter progress while detecting resets and implausible regressions.
  5. Project current state. Update the operator-facing session without discarding raw event evidence.

Handle counters at their real width

Classic input and output octet attributes are 32-bit counters. Busy sessions can exceed that range. Devices may send gigaword attributes that extend the counter; the collector must combine them correctly. A graph that drops at the rollover point is not a customer suddenly returning traffic.

total_input_octets  = (Acct-Input-Gigawords  × 4294967296) + Acct-Input-Octets
total_output_octets = (Acct-Output-Gigawords × 4294967296) + Acct-Output-Octets

Test the exact NAS firmware. Counter direction can also confuse reporting: from the NAS perspective, input is traffic received from the subscriber and output is traffic sent toward the subscriber. Label customer-facing upload and download only after confirming that viewpoint.

Select an Interim interval from recovery needs

A shorter interval improves freshness and limits the amount of usage lost when a Stop is missing, but it increases packet rate and database writes. The correct value follows from session volume, database capacity and how quickly operations must detect stale or anomalous sessions.

5mis a common starting point, not a universal rule; load-test it against peak concurrent sessions and storage design.

Batching and indexed upserts can reduce write pressure. Avoid an index on every dashboard filter; each index also adds work to a high-frequency write path.

Reconcile sessions that cannot close cleanly

A power loss cannot send a Stop. A tunnel failure can hide packets. A router reboot may invalidate sessions that the database still calls online. Reconciliation should compare accounting freshness with NAS reality and use a named closure reason.

  • Mark a session stale only after a threshold longer than the configured Interim interval and expected network delay.
  • Use Accounting-Off or router restart evidence to close affected sessions in a controlled batch.
  • Query the NAS for active sessions when safe and map responses through the composite identity.
  • Keep inferred closure distinct from a received Stop.
  • Do not change historical octets merely to make a dashboard look tidy.

Keep usage evidence separate from charging

Accounting records can support quota, fair-use and usage-based products, but they are not invoices. A charging process should consume finalized usage under a declared measurement window, tariff and rounding rule, then create an auditable financial event.

This boundary matters when late packets arrive. Operational session data may be corrected while a previously issued invoice remains governed by credit-note and adjustment rules. Directly editing invoice totals whenever an Interim packet changes creates an accounting system that cannot close a period.

Monitor the pipeline, not only the daemon

  • Accepted accounting packets per NAS and status type.
  • Authentication failures and packets from unknown NAS sources.
  • Time from packet receipt to durable database commit.
  • Sessions older than the stale threshold without a recent Interim.
  • Counter regressions, rollovers and implausible rate spikes.
  • Open sessions associated with subscribers whose desired entitlement is inactive.

Primary references: IETF RFC 2866, current FreeRADIUS accounting guidance, and RouterOS AAA documentation. Counter and retry behaviour should be verified with packet captures from every NAS family and firmware train used in production.

Continue with ISPbills

Put this guide into practice