Collected every 20 seconds
The agent reads WireGuard's per-peer byte counters, computes deltas per peer instance, and batches them upward every minute.
Idempotent on retry
Every batch carries a per-session sequence number. The master keeps the last one it accepted and ignores anything at or below it.
Hourly, then daily
Deltas fold into hourly buckets per session, user and node. A nightly job rolls buckets older than ninety days into daily rows.
Per-peer counters reset, and that is not an error
WireGuard's counters are monotonic per peer — and a peer is removed and re-added on every single reconnect, which resets them to zero. Naively diffing produces either a huge negative delta that gets dropped, or worse, a double count after an agent restart.
The collector keeps the last reading per peer instance and applies:
// a reading lower than the last one means the counter reset, // so the current value IS the delta delta = current >= last ? current - last : current;
The cursor is persisted to local storage on the node, so restarting the agent does not re-report a session's entire history.
Quota size
Per user, in bytes. Unset means unlimited.
Period
Weekly, monthly, or none. Rolls forward as many periods as have actually elapsed, so an account idle for three months comes back with a full allowance and a start date that is not in the past.
Enforcement point
The ingest path and the lease path — not a nightly batch. Crossing a quota revokes live sessions and refuses new tickets, and the user is offline within roughly one lease interval.
Reset
An administrator can zero the period's usage without waiting for the rollover, and the action is audited.
Rate limit
Optional megabits per second, per user, applied by the node when the peer is installed.
Enforced where the bytes arrive
Because enforcement rides on the path that receives the counters rather than a scheduled job, someone who blows through their allowance stops within about a lease interval — not at midnight.
The user's period total is a denormalized counter so the hot check is one column. The authoritative history stays in the hourly records, which is what the console's reports read.
- Reports by user, by node and by day, over any window
- A retried batch after a network timeout has no effect — without that, a flaky link inflates every user's usage
- Table growth is linear in active users × hours, not in packets
Everything expires, and the windows are yours to set
Sessions
12 months by default.
Hourly usage
90 days, then rolled into daily rows.
Daily usage
24 months.
Client IP
30 days — the one genuinely privacy-relevant field, and separately configurable for that reason.
Connect tickets
7 days.
Audit
24 months.
Need different numbers?
Every window above is configuration. Tell us the shape of your deployment and we will tell you what to change.