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.
Layout at a glance
Section titled “Layout at a glance”┌────────────────────────────────────────────────────────────────────┐│ 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.
:::
How to get here
Section titled “How to get here”| Where | How |
|---|---|
| URL | /dashboard or simply / after login |
| Sidebar | Top item, chart icon |
| Audience | Every user type — admin, reseller, sub-reseller, support, collector, read-only |
| Permission | None required — what you see is scoped by your permissions |
Section 1 — Subscribers
Section titled “Section 1 — Subscribers”Every card is clickable and acts as a one-click filter shortcut into the Subscribers list.
| Card | Counts | Click takes you to |
|---|---|---|
| Non-deleted rows in your scope | Subscribers (no filter) | |
is_online = true, synced every 30 s | Subscribers · status = online | |
| Total minus online | Subscribers · status = offline | |
status = active AND not expired | Subscribers · active filter | |
| Operator or system has disabled the account | Subscribers · inactive filter | |
expiry_date < today | Subscribers · expired filter | |
expiry_date falls in the next 7 days | Subscribers · expiring filter | |
created_at >= 1st of current month | Subscribers · new this month |
How “Online” is computed
Section titled “How “Online” is computed”A subscriber counts as online only when all three are true:
subscribers.is_online = true(set by QuotaSync).- There is an open row in
radacct(acct_stop_time IS NULL) for the username. - The last
acct_update_timeis within the past 30 minutes — older = stale, swept automatically.
Section 2 — Revenue & Sessions
Section titled “Section 2 — Revenue & Sessions”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 createdrenewal— 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.
| Card | Window | Filter |
|---|---|---|
| Today’s Subscriptions | created_at >= today 00:00 | type IN ('new', 'renewal') |
| Month Subscriptions | created_at >= 1st of current month | type 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_topupprepaid_card subscriber_topup subscriber_purchasereset_fup rename
* legacy spelling — kept for backwards-compat with old dataThree types are deliberately excluded — they are accounting movements, not income:
transfer withdraw refundThese cards match the totals shown in Reports → Revenue. Both views share the same canonical list, so the numbers always agree.
Why two numbers instead of one
Section titled “Why two numbers instead of one”Other cards in this section
Section titled “Other cards in this section”| Card | What it shows |
|---|---|
| Active Sessions | Live count of radacct rows with acct_stop_time IS NULL — literal PPPoE sessions currently up on your BNG. |
| Total Resellers | |
| Unpaid Invoices + Unpaid Amount | Count and sum of invoices.status = pending. |
Section 3 — System Metrics
Section titled “Section 3 — System Metrics”::: 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).
| Metric | What it measures | Watch out when |
|---|---|---|
| CPU | 5-second average load across all cores | |
| Memory | Used / total host RAM | |
| HDD | Used / total on / |
::: 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. :::
Section 4 — Trends & activity
Section titled “Section 4 — Trends & activity”New vs. expired — 30-day trend chart
Section titled “New vs. expired — 30-day trend chart”A two-line chart, one point per day, last 30 days:
| Line | What it plots |
|---|---|
subscribers.created_at = that day | |
subscribers.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.
Top Resellers
Section titled “Top Resellers ”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.
Recent transactions
Section titled “Recent transactions”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.
Common workflows
Section titled “Common workflows”Are my customers all online?
- Glance at Online vs. Total Subscribers in Section 1.
- Ratio under 50%? Click Offline to see who is disconnected.
- Cross-reference with Active Sessions in Section 2 — if the session count is much lower than the online count, you have stale
is_onlineflags. Wait five minutes for the cleanup sweeper, or restart the API container.
How much did I earn today?
- Read Today’s Total Income — every paying transaction since 00:00.
- Compare against Today’s Subscriptions — the difference is from top-ups, plan changes, prepaid sales, etc.
- For the breakdown by transaction type, click through to Reports → Revenue.
Anyone about to expire?
- Click Expiring — opens Subscribers filtered to those expiring in the next 7 days.
- Select all → Bulk Action → Send WhatsApp reminder (if Communication Rules are wired up).
- Or use Bulk Action → Renew to auto-renew them all where their reseller has the balance.
Why is CPU at 95%?
- Confirm in the System Metrics bar (Section 3).
- Open Logs → System Logs in another tab.
- Filter by
level=warnorlevel=error. Common culprits: a single subscriber flapping, a long-running CSV import, a stuck PDF render. - If the spike is regular every 30 seconds, that is QuotaSync — stagger NAS scrape times.
Permissions
Section titled “Permissions”The Dashboard page itself does not require any permission — every authenticated user reaches it. What appears on it is permission-scoped:
| Permission | Effect |
|---|---|
subscribers.view_all | Subscriber stat cards and the trend chart show system-wide totals (otherwise scoped to your own subscribers). |
transactions.view_all | Revenue cards aggregate all transactions, not just your own. |
sessions.view_all | Active Sessions counter shows the global count. |
dashboard.view_admin | Surfaces 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.
Customization
Section titled “Customization”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.