Monitoring the CPU load on the 1C-Bitrix server

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1173
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    745
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    976

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%.