Bitrix Memory Leak Diagnosis and Optimization: Monitoring Strategies

When a server with 8 GB RAM runs an import from 1C, memory can be exhausted within 15 minutes if monitoring is not configured. During peak daytime load, the site starts to slow down or returns 503 errors. Most often, the issue is insufficient RAM for PHP-FPM workers. Each request consumes memory,

Our competencies:

Frequently Asked Questions

When a server with 8 GB RAM runs an import from 1C, memory can be exhausted within 15 minutes if monitoring is not configured.

During peak daytime load, the site starts to slow down or returns 503 errors. Most often, the issue is insufficient RAM for PHP-FPM workers. Each request consumes memory, and if workers don't release it quickly enough, the server starts swapping. We'll show you how to track the problem and set up monitoring to avoid downtime.

With over 10 years of experience with Bitrix and 50+ optimization projects, we've tested dozens of configurations and developed a methodology that reduces RAM usage by 20–30% without sacrificing speed.

Why is memory a bottleneck in Bitrix?

PHP does not share memory between workers: each worker process lives independently. With pm.max_children = 50 and an average consumption of 128 MB per worker, that's 6.4 GB just for PHP. Add system processes, the database (MySQL), and the web server. If the total exceeds available RAM, swapping begins, and response times increase dramatically.

The most memory-intensive operations:

  • Import via CommerceML (XML files are read entirely, a worker can consume 300+ MB).
  • Complex infoblock queries without limits (CIBlockElement::GetList() without filters).
  • Third-party modules with leaks (static properties, uncleaned global arrays).
  • Unreleased cache at the PHP level (managed_cache + memcached duplicates data).

Understanding resident set size (RSS) and memory fragmentation is crucial; workers' RSS directly impacts RAM availability and can trigger the OOM killer if limits are exceeded.

How to diagnose memory consumption?

At the system level, the easiest way is to check the RSS of each worker:

ps aux --sort=-%mem | grep php-fpm | awk '{sum += $6} END {print sum/1024 " MB"}' 

Or in detail: ps aux | grep php-fpm | awk '{print $6/1024 " MB\t" $11}'.

In code, you can place diagnostics in OnEndBufferContent, as in the example below. This catches heavy pages without system overhead.

// Shows peak memory consumption during request lifetime $peak = memory_get_peak_usage(true); if ($peak > 64 * 1024 * 1024) { // > 64 MB \Bitrix\Main\Diag\Debug::writeToFile( sprintf('Peak memory: %.1f MB, URI: %s', $peak / 1048576, $_SERVER['REQUEST_URI']), 'MEM_HIGH', '/local/logs/memory.log' ); } 

For continuous monitoring, we use the Prometheus + node_exporter + Grafana stack. The metric node_memory_MemAvailable_bytes shows free memory. An alert when it drops below 512 MB forces you to react before the site crashes.

Example alert in Prometheus
- alert: LowMemory expr: node_memory_MemAvailable_bytes < 536870912 for: 5m annotations: summary: "Low RAM on {{ $labels.instance }}" 

How to reduce consumption by 30%?

One of the most effective parameters is pm.max_requests. It forces a worker to restart after N requests, resetting potential leaks. For projects with imports and third-party modules, we set it to 200–500. Setting pm.max_requests reduces RAM usage by 20–30%, which is twice as effective as simply limiting memory_limit (10–15%). This makes pm.max_requests 2 times better than memory_limit adjustment alone for memory leak prevention.

The second is limiting memory_limit. We recommend 256 MB for a typical site. This suffices for 95% of operations; heavy imports can be moved to separate agents with a 512 MB limit.

The third is caching. Enabling tagged caching in infoblocks and disabling duplication in managed_cache saves 10–15% memory.

Compare approaches:

Approach RAM Reduction Implementation Complexity
pm.max_requests = 500 20–30% Low (1 parameter)
memory_limit = 256M 10–15% Medium (code analysis)
Cache optimization 10–20% Medium (infoblock setup)
Streaming import replacement 30–50% High (module rework)

According to 1C-Bitrix documentation, the optimal memory_limit for a typical site is 256 MB. However, for heavy operations, it is recommended to increase the limit in separate agents.

Case study from our practice: online store with daily imports

We were contacted by the owner of an online store on Bitrix, where the import from 1C started at 2:00 AM. After the import, several workers remained at 250–300 MB RSS, and the server (8 GB) went into swap. Until 7:00 AM, the site was sluggish.

We found that pm.max_requests was 0, meaning workers were never restarted. We set pm.max_requests = 200 and limited memory_limit to 256 MB (previously 512). Result: bloated workers died after 200 requests, returning memory to the system. The site stopped lagging, and import time decreased by 15% due to less swapping. Thanks to this configuration, the client significantly reduced server rental costs.

What's included in the work?

When ordering monitoring and memory optimization, we:

  1. Analyze current PHP-FPM configuration, caching, and load — conduct a performance audit.
  2. Set up metric collection (Prometheus + node_exporter).
  3. Optimize pm parameters, memory_limit, and caching.
  4. Add diagnostics to code (peak logging).
  5. Train the team to use dashboards and alerts.
  6. Provide a detailed report with recommendations, documentation of all changes, and grant access to the monitoring dashboards. Guarantee performance improvement.
  7. Offer one month of post-optimization support to ensure stability.

Estimated timelines

Diagnosis and setup take from 2 to 5 business days, depending on project complexity. Cost is calculated individually after analyzing the current configuration.

Common memory configuration mistakes

One common mistake is setting pm.max_children too high, leading to RAM overflow and swapping. Also, it is not recommended to set the same memory_limit for all requests, as heavy operations kill workers. Lack of monitoring means leaks are only noticed when the site crashes. Untagged cache duplicates data, wasting memory.

Get an engineer's consultation — we'll evaluate your configuration for free. Order a performance audit of your Bitrix project — we'll find bottlenecks and offer solutions. If you notice site slowdowns, contact us for a free consultation.

Links: PHP-FPM configuration, Bitrix cache management, Wikipedia: PHP-FPM.

How to set up memory monitoring in one hour?

Another example: setting up simple monitoring via pm.status_path. Enable pm.status_path = /status in the PHP-FPM pool, then request metrics via script or Prometheus exporter. This gives active worker count and average consumption.

Tool Setup time Detail level
pm.status_path 15 minutes Basic (workers, queue)
node_exporter + Prometheus 2 hours Full (RAM, CPU, disk)
Bitrix environment (push & pull) 1 hour Only notifications

On average, memory optimization can lead to significant monthly savings. Contact us to discuss your tasks.