Skip to content
NOWACRM Docs

Operator documentation

FUP & Data Limit Lifecycle Architecture

This document explains how NowaCRM handles Fair Usage Policy (FUP), Data Limits, tracking, and enforcement across the RADIUS ecosystem.

FUP & Data Limit Lifecycle Architecture

This document explains how NowaCRM handles Fair Usage Policy (FUP), Data Limits, tracking, and enforcement across the RADIUS ecosystem.

1. Data Usage Tracking

Data tracking is robust against archiving and long-running sessions. The system calculates total usage dynamically by combining two sources:

Total Usage = Aggregated History + Live Active Sessions

  • Aggregated History (radius_daily_usage): Stores completed session data per day. Populated nightly by RadiusDailyAggregationJob and real-time by IngestRadiusAccounting when a session stops. This data is never archived, ensuring permanent historical accuracy.
  • Live Active Sessions (radacct): Real-time data from sessions currently online (acctstoptime IS NULL). FreeRADIUS sends interim updates which update the radacct table.

Benefit: Even if a session runs for 3 days and older radacct rows are archived, the combination ensures 0 MB of data loss.

Reference: App\Services\FupService::getCurrentCycleUsage()

2. Limit Priority (Plan vs. Manual)

The system uses an "Effective Limit" concept.

  • Manual Limit (data_limit_override_bytes): Set by the ISP via the UI ("Set Data Limit"). This has the highest priority.
  • Plan Limit: If no manual limit exists, the system falls back to the subscriber's base plan limit.

Reference: App\Models\Subscriber::effectiveDataLimit()

3. Enforcement Mechanisms

Enforcement happens at two critical points:

A. During Login (Offline Users)

When a user attempts to connect, RadiusAuthController@authorize checks their usage against the effectiveDataLimit.

  • If Usage < Limit: Access-Accept.
  • If Usage >= Limit (FUP Plan): Access-Accept with throttled speeds via Mikrotik-Rate-Limit.
  • If Usage >= Limit (Hard Limit, Non-FUP): Access-Reject.

B. During Active Session (Online Users)

A background cron job (php artisan radius:check-fup) runs every 5 minutes to monitor active users.

  • If a user crosses their effectiveDataLimit while online, the FupService triggers.
  • For FUP Plans: Sends a RADIUS CoA (Change of Authorization) to instantly throttle their speed.
  • For Hard Limits (Non-FUP): Sends a RADIUS Disconnect (Kick) to terminate the session immediately and clears their Redis Auth cache.

4. Top-Up and Reset Flows

When a user exhausts their limit, the ISP can increase the limit via the UI (e.g., changing 100GB to 150GB). The background cron or next login will immediately recognize the new headroom.

Reset Data Usage

If an ISP clicks "Reset Data Usage" in the subscriber profile:

  1. The system wipes the accumulated history in radius_daily_usage only for the current billing cycle.
  2. It sends a RADIUS Disconnect command to kick active sessions. This flushes any pending radacct bytes so they don't carry over.
  3. The user reconnects with exactly 0 Bytes used.

Reference: App\Http\Controllers\ISP\SubscriberController::resetDataUsage()