1C-Bitrix Performance Optimization Services

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
    1175
  • 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
    747
  • 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

Performance Optimization for 1C-Bitrix Websites

b_iblock_element_property — the table behind 80% of performance issues on Bitrix projects. EAV structure: one row per value per property per element. A catalog of 50,000 products with 30 properties — one and a half million rows. The smart filter JOINs this table with b_iblock_element across five properties — and MySQL goes into a full table scan for 3-5 seconds. Bitrix optimization starts with this table and radiates across the entire infrastructure.

Server-Side Optimization

Nginx. Not just "enabled gzip." Specifically:

  • gzip_comp_level 4-5 — higher is pointless, CPU consumes more than it saves in bandwidth
  • brotli on with brotli_static on — for pre-compressed files
  • HTTP/2 with http2_max_concurrent_streams 128
  • fastcgi_cache for PHP responses — caching at the Nginx level, bypassing PHP-FPM entirely
  • worker_processes auto, worker_connections tuned to actual concurrent connections

PHP-FPM. The choice between pm = dynamic and pm = static is not academic:

  • Static: fixed number of workers, no fork overhead. For dedicated servers with predictable load
  • Dynamic: saves RAM during low traffic. pm.max_children calculated as (available RAM - RAM for MySQL/Redis) / average memory per process
  • OPcache: opcache.memory_consumption=256, opcache.max_accelerated_files=20000, opcache.validate_timestamps=0 in production (PHP-FPM restart on deploy)

MySQL/MariaDB. Almost always the main bottleneck:

  • slow_query_log with a 0.5 sec threshold. Every query analyzed via EXPLAIN
  • innodb_buffer_pool_size = 70-80% of available RAM on a dedicated server
  • query_cache_type = 0 on MySQL 8.x (query cache removed) or MariaDB with query_cache_size tuned to load profile
  • Composite indexes for faceted search: (IBLOCK_ID, IBLOCK_PROPERTY_ID, VALUE) on b_iblock_element_property
  • OPTIMIZE TABLE b_iblock_element_property after bulk operations

Caching: Three Levels

Managed component cache. TTL configured individually per component. Catalog — 3600 sec, news feed — 300 sec, banners — 86400. Identical TTL everywhere guarantees either stale data or useless cache.

Composite cache. The "Composite Site" technology (bitrix:composite). Nginx serves ready-made HTML from a file, PHP doesn't launch. Dynamic zones (cart, authentication, regional content) are loaded via an AJAX request through CBitrixComponent::setFrameMode(true). TTFB < 50 ms. But: not all components are compatible, $APPLICATION->ShowPanel() and direct output via echo break the composite. We verify each page via the "Performance → Composite Site" panel.

Memcached / Redis. Moving cache out of the filesystem:

  • Sessions → Redis (session.save_handler = redis). 10-50x faster than file storage, plus works in a cluster
  • Component cache → Memcached via .settings.php: 'cache' => ['type' => 'memcache']
  • ORM query cache — so identical GetList() calls don't hit MySQL on every request

Frontend

Images — 60-80% of page weight:

  • WebP via CFile::ResizeImageGet() with BX_RESIZE_IMAGE_PROPORTIONAL + conversion
  • srcset + sizes — don't load a 3000px image into a 400px block
  • loading="lazy" for everything below the fold
  • AVIF for browsers that support it — another 20-30% savings vs WebP

CSS/JS:

  • Built-in Bitrix module: bundling and minification via "Settings → CSS/JS Optimization"
  • PurgeCSS / UnCSS — on a typical Bitrix project, 60-70% of CSS is unused (styles from all connected components are pulled in)
  • defer / async for non-critical JS
  • Critical CSS inlined in <head> for instant FCP

Fonts:

  • <link rel="preload" as="font" crossorigin> for the primary font
  • font-display: swap — text is visible immediately, font loads in the background
  • Subsetting via pyftsubset — extract Cyrillic + Latin, everything else is unnecessary. File size reduced 3-5x

CDN

  • Cloudflare, BunnyCDN, AWS CloudFront, or Russian providers (Selectel CDN, VK Cloud CDN)
  • Static assets (CSS, JS, images, fonts) — via CDN
  • Cache rules: Cache-Control: public, max-age=31536000, immutable for files with a hash in the name
  • imgproxy or Cloudflare Polish — on-the-fly image optimization without loading the origin

Load Testing

Not synthetic benchmarks, but real scenarios:

  • k6 / wrk — simulating routes: catalog → filtering → product card → cart → checkout
  • Metrics: RPS, response time (p50, p95, p99), error rate
  • Xdebug (callgrind) or Blackfire — PHP profiling, finding specific bottlenecks. We see that CIBlockElement::GetList() with five PROPERTY_* filters takes 2 sec — we optimize exactly that call

Database Optimization: Beyond Standard Settings

Indexes. Composite indexes for faceted search. Covering indexes for frequent queries — MySQL responds from the index without touching data. Partial indexes (MariaDB) for filtering by ACTIVE = 'Y'. Audit of unused indexes — each one slows down INSERT/UPDATE.

Partitioning. For tables with millions of rows: b_stat_session, b_search_content_stem, Highload blocks with history. Partitioning by date — a query for "orders this month" doesn't scan three years of data.

Cleanup. Every Bitrix database accumulates over a year or two: stale search index in b_search_content, expired records in b_cache_tag, b_iblock_element_prop_s* history spanning years, gigabytes of logs in b_event_log. We set up regular cleanup via agents.

Results

Metric Before After
TTFB 800-2000 ms 50-200 ms
Full page load 4-8 sec 1.5-2.5 sec
PageSpeed (mobile) 30-50 80-95
Concurrent users 50-100 500-2000+

Monitoring

Without monitoring, everything degrades within six months. A new module, uncleaned logs, a template change — and speed returns to its original state.

  • web-vitals API — Real User Monitoring from actual visitors
  • Synthetic monitoring — Pingdom, UptimeRobot, regular checks from multiple locations
  • Alerts — TTFB > 500 ms or LCP > 3 sec → notification

Hosting

Type Best For Limitations
Shared Landing pages, up to 500 visits/day No control over PHP-FPM, Redis, Nginx
VPS/VDS Most projects Up to 30K visits/day with proper configuration
Dedicated Large stores Full control, NVMe, plenty of RAM
Cloud (Yandex Cloud, VK Cloud, AWS) Uneven load Auto-scaling during sales, fault tolerance

Pricing

Type of Work Timeline Cost
Basic optimization (cache, images, minification) 2-3 days from 25,000 RUB
Database optimization (indexes, slow queries, tuning) 3-5 days from 40,000 RUB
Server infrastructure (Nginx, PHP-FPM, Redis) 2-3 days from 30,000 RUB
Comprehensive (server + DB + frontend + CDN) 1-3 weeks from 80,000 RUB
Load testing and profiling 2-3 days from 20,000 RUB
Cluster architecture (load balancing, replication) 1-2 weeks from 120,000 RUB

Reducing TTFB by 1 second yields approximately +7% to conversion. For a store with 5M/month revenue — that's 350K in additional monthly revenue.