CPU Load Monitoring for a 1C-Bitrix Server
CPU load on a Bitrix server grows gradually, and performance degradation is usually noticed only when the load average has already hit 10–20 on a 4-core machine and requests start timing out. By that point, diagnosing the root cause is harder — you need historical load data. Properly configured monitoring captures anomalies at the moment they occur.
Sources of CPU Load in Bitrix
CPU usage in a PHP application is distributed across several processes:
- php-fpm — PHP code execution: page generation, form handling, cron jobs
- mysqld / mariadb — SQL queries: sorts, JOINs without indexes, COUNT(*)
- nginx — static file serving, SSL offloading, gzip compression
- opcache invalidation — during frequent deployments, PHP recompiles files
It is important to distinguish: if CPU is 90% consumed by mysqld, the problem is not in PHP. top, htop, and pidstat will show the breakdown.
Monitoring Tools
Quick real-time diagnostics:
# CPU by process, updated every 2 s
htop -d 20
# Per-core load (mpstat from sysstat)
mpstat -P ALL 5
# What a specific php-fpm process is doing
strace -p [PID] -e trace=network,file -T 2>&1 | head -50
PHP-FPM status:
# If pm.status_path = /php-fpm-status is configured
curl -s http://127.0.0.1/php-fpm-status?full | grep -E "status|active|idle|requests"
Watch active processes — if it consistently equals max_children, there are not enough workers and requests are queuing. This is not high CPU per se, but the symptom is similar: the site becomes slow.
Prometheus + Grafana — continuous monitoring:
Metrics from node_exporter:
# CPU utilization per core (excluding idle)
100 - (avg by(cpu)(rate(node_cpu_seconds_total{mode="iowait"}[5m])) * 100)
# Overall load
100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# load average / number of cores
node_load1 / count(count(node_cpu_seconds_total{mode="idle"}) by (cpu))
Alert when load average / cores exceeds 2 for 10 minutes:
- alert: HighCPULoad
expr: (node_load1 / count(count(node_cpu_seconds_total) by (cpu))) > 2
for: 10m
labels:
severity: warning
Bitrix Cron Jobs as a CPU Load Source
Bitrix uses cron_events (the b_agent table) — agents run on each page request via pseudo-cron or via a real cron job. Long-running or frequently triggered agents consume CPU:
-- Find heavy agents
SELECT NAME, MODULE_ID, LAST_EXEC, NEXT_EXEC,
TIMEDIFF(NEXT_EXEC, LAST_EXEC) AS period
FROM b_agent
WHERE ACTIVE = 'Y'
ORDER BY LAST_EXEC DESC
LIMIT 20;
Agents such as CSearch::IndexAjax() or CCatalogImport::ImportByAgent() can consume several seconds of CPU per run on large catalogs. Move them to a real cron job with a time limit:
# /etc/cron.d/bitrix
*/5 * * * * www-data /usr/bin/php -f /var/www/bitrix/bitrix/modules/main/tools/cron_events.php > /dev/null 2>&1
Case Study: Peak Load at Noon
An online store: every day between 12:00–13:00 CPU reached 95–100%, and the site responded with 10–30 s delays. The rest of the day the load was 20–30%. Using atop (which records history by default), the culprit was found: the search index update agent (CSearch::IndexAjax) was running during that interval, configured with PERIOD = 3600 seconds but triggered 12 times within an hour (12 parallel requests on different pages all initiated it). After moving the agent to a real cron job with a nice -n 19 constraint, peak load dropped to 45%.







