Skip to content

perf: Resolves 100% CPU Database spike with User Listing and Dashboard load times#673

Open
retho-p wants to merge 2 commits intolirantal:masterfrom
retho-p:master
Open

perf: Resolves 100% CPU Database spike with User Listing and Dashboard load times#673
retho-p wants to merge 2 commits intolirantal:masterfrom
retho-p:master

Conversation

@retho-p
Copy link
Copy Markdown
Collaborator

@retho-p retho-p commented Apr 20, 2026

Description:
This PR introduces vital database index definitions and refactors the underlying PHP logic to stabilize performance for large deployments.

Previously, instances with active accounting enabled and thousands of users (e.g., resulting in ~1,000,000+ rows in radacct) experienced cascading, multi-minute UI hangs on the List Users and Dashboard pages. MySQL would hit 100% CPU while trying to perform full table scans across massive datasets just to configure pagination or calculate dashboard aggregations (Top 10 users last month, Currently Online, etc).

Key Fixes

  • PHP Decoupling (app/operators/mng-list-all.php):
    The LEFT JOIN to radacct was removed from the core session table structure. The row-count function now scales effortlessly, and lastlogin timestamps are queried independently post-LIMIT, significantly reducing memory consumption during $res->numRows().

  • Dashboard Covering Indexes:
    The MySQL schema now builds composite B-Tree indexes specifically targeting heavy dashboard OLAP queries. Operations that previously executed a filesort over a million raw rows now resolve directly in RAM via index lookups.

  • Idempotent Update Script:
    Migrated systems will not encounter index collision errors. A robust stored-procedure update script ensures safe deployments in automated pipelines.

Testing & Verification

  • Load tested successfully
    The failure scenario was explicitly replicated in an isolated test environment by generating 10,000 mock users and scaling to 1,000,000 radacct session records to emulate a long-running production system.

    • Before the fix:
      Accessing the endpoint triggered a massive CPU spike, locking MySQL at 100% and causing the UI to hang for several minutes.

    • After the fix:
      Using the same dataset, the page renders in milliseconds.

🚀 Release Notes for Production Environments

If you are running an existing production instance of daloRADIUS, applying this update will resolve dashboard and user listing slowdowns.

Because new standard indexes were introduced to the SQL schema, you must update your existing database for the changes to take full effect. A fully safe, idempotent migration script is provided and can be executed on a live system without risk of data loss or index conflicts.

Apply the update

  1. Update your daloRADIUS installation to this latest version.
  2. Run the following command in your terminal (adapt to your environnement):
cd /var/www/daloradius/contrib/db
mysql -u root -p radius_database_name < update-performance-indexes.sql

Note:
Please ensure you have a full backup of your environment and database before applying this update.
Depending on the size of your radacct table, this operation may take between 5–30 seconds. The system can remain online during execution.

- Refactored `mng-list-all.php` to decouple `radacct` from the base counting queries, preventing catastrophic Cartesian joins when calculating pagination.
- Replaced the heavy base query with a fast uncorrelated subquery fetching `lastlogin`.
- Introduced `contrib/db/update-performance-indexes.sql`, a fully idempotent migration script to deploy essential Covering Indexes for heavily aggregated tables.
- Appended foundational performance indexes directly to the `mariadb-daloradius.sql` schema so new installations obtain them automatically.
- Resolves severe MySQL 100% CPU spikes and multi-minute page hangs when scaling to >10,000 users and millions of accounting records.
@retho-p
Copy link
Copy Markdown
Collaborator Author

retho-p commented May 4, 2026

This PR will fix #634 also

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants