Skip to content

Dashboard

The Dashboard is the landing page after login. It is built to answer four questions at a glance, refreshes every 30 seconds, and is the only page every user type lands on by default.

Online / offline counts, total subscribers, active sessions — at a glance. Today and month revenue (subscriptions + total income), unpaid invoices. Expired, expiring within 7 days, FUP-tier distribution. CPU, memory, disk usage. Admins only — hidden from resellers and from SaaS tenants.
┌────────────────────────────────────────────────────────────────────┐
│ PROXPANEL 🌙 admin ▼ │
├────────────────────────────────────────────────────────────────────┤
│ │
│ Subscribers ───────────────────────────────────────────────── ▼ │
│ ┌──────┬──────┬──────┬──────┬──────┬──────┬──────┬──────┐ │
│ │Total │Online│Offln │Active│Inact │Exprd │Exprng│New/M │ │
│ │ 24K │ 18K │ 6K │ 22K │ 2K │ 412 │ 89 │ 1.2K │ │
│ └──────┴──────┴──────┴──────┴──────┴──────┴──────┴──────┘ │
│ │
│ Revenue & Sessions ────────────────────────────────────────── ▼ │
│ ┌──────┬──────┬──────┬──────┬──────┬──────┐ │
│ │ Today│ Month│ Today│ Month│Active│Total │ │
│ │ Subs │ Subs │ Total│ Total│Sess │Resel │ │
│ └──────┴──────┴──────┴──────┴──────┴──────┘ │
│ │
│ System Metrics (admin) ────────────────────────────────────── ▼ │
│ CPU ▰▰▰▰▰▱▱▱▱▱ 42 % │
│ MEM ▰▰▰▰▰▰▰▱▱▱ 67 % │
│ HDD ▰▰▱▱▱▱▱▱▱▱ 18 % │
│ │
│ Trends ────────────────────────────────────────────────────── ▼ │
│ [ 30-day new vs. expired line chart ] [ Top resellers ] │
│ [ Recent transactions feed ] │
└────────────────────────────────────────────────────────────────────┘

::: Every number on this page comes from a server-side cache that refreshes every 30 seconds. At 25,000 subscribers, a single uncached render would issue 13+ COUNT(*) queries — the cache reduces that to one read per 30 s and keeps the page snappy at scale. :::

WhereHow
URL/dashboard or simply / after login
SidebarTop item, chart icon
AudienceEvery user type — admin, reseller, sub-reseller, support, collector, read-only
PermissionNone required — what you see is scoped by your permissions

Every card is clickable and acts as a one-click filter shortcut into the Subscribers list.

CardCountsClick takes you to
Non-deleted rows in your scopeSubscribers (no filter)
is_online = true, synced every 30 sSubscribers · status = online
Total minus onlineSubscribers · status = offline
status = active AND not expiredSubscribers · active filter
Operator or system has disabled the accountSubscribers · inactive filter
expiry_date < todaySubscribers · expired filter
expiry_date falls in the next 7 daysSubscribers · expiring filter
created_at >= 1st of current monthSubscribers · new this month

A subscriber counts as online only when all three are true:

  1. subscribers.is_online = true (set by QuotaSync).
  2. There is an open row in radacct (acct_stop_time IS NULL) for the username.
  3. The last acct_update_time is within the past 30 minutes — older = stale, swept automatically.

Four revenue cards plus the active-session and reseller counters. The four revenue cards expose two distinct metrics side by side — the same approach used by enterprise ISP platforms.

Subscription revenue (MRR)

The two Subscription cards count exactly two transaction types:

  • new — first charge when a subscriber is created
  • renewal — recurring charge when a subscriber renews

This is the classic Monthly Recurring Revenue metric — predictable income for forecasting, churn analysis, and showing the business’s value.

CardWindowFilter
Today’s Subscriptionscreated_at >= today 00:00type IN ('new', 'renewal')
Month Subscriptionscreated_at >= 1st of current monthtype IN ('new', 'renewal')

Total income (all sources)

The two Total Income cards count all 13 income-side transaction types:

new renewal change_service service_change*
static_ip addon refill data_topup
prepaid_card subscriber_topup subscriber_purchase
reset_fup rename
* legacy spelling — kept for backwards-compat with old data

Three types are deliberately excluded — they are accounting movements, not income:

transfer withdraw refund

These cards match the totals shown in Reports → Revenue. Both views share the same canonical list, so the numbers always agree.

Answers *"How predictable is my income?"* — used for forecasting, valuations, churn analysis. Stable. Comparable month over month. Answers *"How much money came in this month?"* — used for accounting, cash flow, comparison against Reports. Includes top-ups, fees, plan changes.
CardWhat it shows
Active SessionsLive count of radacct rows with acct_stop_time IS NULL — literal PPPoE sessions currently up on your BNG.
Total Resellers Hidden in the reseller view.
Unpaid Invoices + Unpaid AmountCount and sum of invoices.status = pending.

::: This row is hidden from reseller logins. It is also hidden from tenant admins in SaaS mode — the underlying server is shared infrastructure, not the tenant’s to monitor. :::

Three live progress bars sourced from the host’s /proc (bind-mounted into the API container so metrics reflect the VM or bare-metal, not the container).

MetricWhat it measuresWatch out when
CPU5-second average load across all cores Sustained above 70% for 5+ minutes
MemoryUsed / total host RAM Above 85% — Postgres + Redis are the largest consumers
HDDUsed / total on / Below 15% free — backups will start failing

::: If you see CPU jumping to 100% every 30 seconds, that is QuotaSync hitting all your NAS devices at once. Stagger NAS scrape times, or open Settings → Performance to tune the worker pool. :::

::: If you deploy on LXC instead of a real VM, these metrics will reflect the host node, not your container. Numbers will be misleading. ProxPanel officially supports physical servers, KVM, VMware, and Hyper-V only — see System Requirements. :::

A two-line chart, one point per day, last 30 days:

LineWhat it plots
New subscribers createdsubscribers.created_at = that day
Subscribers expiringsubscribers.expiry_date = that day

Use the shape of the lines to spot:

  • Sales drop-off — blue line trending down (fewer new customers signing up).
  • Churn cliff — red line spiking (lots of expiries without matching renewals).
  • Auto-renewal failures — red spikes without corresponding renewal transactions in the activity feed.

The chart respects scope — a reseller without subscribers.view_all sees only their own subscribers’ trend.

The five resellers with the highest subscriber count this month. Each row shows the reseller name, subscriber count, this-month revenue, and current balance. Click a reseller name to jump to their detail page.

The 10 most recent transactions in your scope. Each row: timestamp, subscriber, type badge (renewal / new / refund / etc.), amount. Click a row to jump to that subscriber’s billing tab.

Are my customers all online?

  1. Glance at Online vs. Total Subscribers in Section 1.
  2. Ratio under 50%? Click Offline to see who is disconnected.
  3. Cross-reference with Active Sessions in Section 2 — if the session count is much lower than the online count, you have stale is_online flags. Wait five minutes for the cleanup sweeper, or restart the API container.

How much did I earn today?

  1. Read Today’s Total Income — every paying transaction since 00:00.
  2. Compare against Today’s Subscriptions — the difference is from top-ups, plan changes, prepaid sales, etc.
  3. For the breakdown by transaction type, click through to Reports → Revenue.

Anyone about to expire?

  1. Click Expiring — opens Subscribers filtered to those expiring in the next 7 days.
  2. Select all → Bulk Action → Send WhatsApp reminder (if Communication Rules are wired up).
  3. Or use Bulk Action → Renew to auto-renew them all where their reseller has the balance.

Why is CPU at 95%?

  1. Confirm in the System Metrics bar (Section 3).
  2. Open Logs → System Logs in another tab.
  3. Filter by level=warn or level=error. Common culprits: a single subscriber flapping, a long-running CSV import, a stuck PDF render.
  4. If the spike is regular every 30 seconds, that is QuotaSync — stagger NAS scrape times.

The Dashboard page itself does not require any permission — every authenticated user reaches it. What appears on it is permission-scoped:

PermissionEffect
subscribers.view_allSubscriber stat cards and the trend chart show system-wide totals (otherwise scoped to your own subscribers).
transactions.view_allRevenue cards aggregate all transactions, not just your own.
sessions.view_allActive Sessions counter shows the global count.
dashboard.view_adminSurfaces System Metrics and Top Resellers.

A read-only partner reseller granted every *.view_all permission sees the same numbers an admin sees, but cannot click through to change anything because they lack the corresponding .edit / .create / .delete permissions.

The Theme tab in Settings exposes 17 CSS variables — accent colors, per-menu-item colors, card backgrounds, badge palettes. Light and dark mode both honour your overrides.