Magento 2 Performance Optimization

Our company is engaged in the development, support and maintenance of sites of any complexity. From simple one-page sites to large-scale cluster systems built on micro services. Experience of developers is confirmed by certificates from vendors.

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1262
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    874
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    851

Magento 2 Performance Optimization

Magento 2 is heavy: default install does 200–400 SQL queries and 50–100 file operations per page. Without special setup, this gives TTFB 3–8 seconds on average server. Goal—reduce to 200–500ms via proper caching stack, PHP config, and eliminating query bottlenecks.

Production Stack

Target architecture:

CDN (Cloudflare/Fastly) → Varnish → Nginx → PHP-FPM 8.2 → MySQL 8.0
                                               ↕              ↕
                                          Redis (cache)   Redis (session)
                                          Elasticsearch (catalog search)

Each layer critical. Varnish gives 85–95% hit rate for anonymous users. Redis removes disk operations on cache. Elasticsearch replaces slow MySQL catalog search.

PHP 8.2 + OPcache + JIT

Magento 2.4.6+ officially supports PHP 8.2. Move from 7.4 gives 15–25% gain on CPU-bound operations.

; /etc/php/8.2/fpm/conf.d/opcache.ini
opcache.enable=1
opcache.memory_consumption=512
opcache.interned_strings_buffer=64
opcache.max_accelerated_files=60000
opcache.validate_timestamps=0
opcache.revalidate_freq=0
opcache.fast_shutdown=1
opcache.enable_cli=1

; JIT — gives 10-20% on Magento computational tasks
opcache.jit=tracing
opcache.jit_buffer_size=256M

PHP-FPM pool:

[magento]
user = www-data
group = www-data
listen = /run/php/php8.2-fpm-magento.sock
listen.backlog = 65535

pm = dynamic
pm.max_children = 40
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 2000

php_admin_value[memory_limit] = 768M
php_admin_value[max_execution_time] = 600
php_admin_value[opcache.file_cache] = /tmp/opcache

Production Mode and Deploy

# Switch to production mode
bin/magento deploy:mode:set production

# DI compilation—generates interceptors, removes reflection overhead
bin/magento setup:di:compile

# Deploy static files with minification
bin/magento setup:static-content:deploy ru_RU en_US -j 4

# Reset and warm cache
bin/magento cache:clean && bin/magento cache:flush

In developer mode Magento recreates DI on every request—5–10x speed difference with production mode.

MySQL 8.0 — InnoDB Tuning

[mysqld]
# InnoDB buffer pool—70% server RAM
innodb_buffer_pool_size = 8G
innodb_buffer_pool_instances = 8

# Redo log
innodb_log_file_size = 1G
innodb_log_buffer_size = 64M

# Flush
innodb_flush_log_at_trx_commit = 2   # 1 = safe, 2 = faster
innodb_flush_method = O_DIRECT

# Parallelism
innodb_read_io_threads = 16
innodb_write_io_threads = 16
innodb_thread_concurrency = 0

# Queries
query_cache_type = 0               # Disable—mutex kills parallelism
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1

Elasticsearch for Search

MySQL search in Magento 2 (LIKE '%query%') unacceptable for 10,000+ SKU catalogs. Elasticsearch gives full-text search with relevance, autocomplete, faceted filtering.

# Install Elasticsearch 8.x
apt install elasticsearch

# Magento configuration
bin/magento config:set catalog/search/engine elasticsearch7
bin/magento config:set catalog/search/elasticsearch7_server_hostname localhost
bin/magento config:set catalog/search/elasticsearch7_server_port 9200
bin/magento config:set catalog/search/elasticsearch7_index_prefix magento2

# Reindex
bin/magento indexer:reindex catalogsearch_fulltext

After reindex, search page with 50,000 products responds in 50–150ms instead of 2–5 seconds.

Indexing and Cron

Magento 2 has indexers recalculated on data change. For large catalogs switch to schedule mode:

# Show current mode
bin/magento indexer:show-mode

# Switch all indexers to schedule (cron update)
bin/magento indexer:set-mode schedule

# Run cron (if no system task)
bin/magento cron:install
bin/magento cron:run

Check indexer status:

bin/magento indexer:status
# catalog_category_product: Ready (last index: 1.2s)
# catalogsearch_fulltext:   Ready (last index: 45.3s)

If catalog_product_price indexer runs > 5 minutes—data volume or catalog_rule problem.

Flat Catalog

For catalogs without complex attributes, Flat Tables speed queries:

bin/magento config:set catalog/frontend/flat_catalog_category 1
bin/magento config:set catalog/frontend/flat_catalog_product 1
bin/magento indexer:reindex catalog_category_flat catalog_product_flat

Flat catalog incompatible with some extensions—check after enabling.

Eliminating N+1 Problems

Diagnose via n98-magerun2:

# Install
composer global require n98/magerun2

# Profile page queries
n98-magerun2 dev:query-log:enable
# Open page in browser
n98-magerun2 dev:query-log:disable
# Analyze var/debug/db.log
grep -c "SELECT" var/debug/db.log

Typical N+1 sources in Magento 2:

  • afterLoad plugins doing queries per collection record
  • EAV attributes without addAttributeToSelect in collection
  • blocks calling $product->load($id) instead of collection

Correct collection loading pattern:

$collection = $this->productCollectionFactory->create();
$collection->addAttributeToSelect(['name', 'price', 'status'])
           ->addFieldToFilter('status', 1)
           ->addFieldToFilter('visibility', ['in' => [2, 3, 4]])
           ->setPageSize(24)
           ->setCurPage(1);
// One query instead of 24+1

CDN for Static Files

# Setup base URL for static via CDN
bin/magento config:set web/unsecure/base_static_url https://cdn.myshop.ru/pub/static/
bin/magento config:set web/secure/base_static_url https://cdn.myshop.ru/pub/static/
bin/magento config:set web/unsecure/base_media_url https://cdn.myshop.ru/pub/media/
bin/magento config:set web/secure/base_media_url https://cdn.myshop.ru/pub/media/
bin/magento cache:flush

Static and media served from CDN servers nearest to user—30–50% page load time reduction for remote regions.

JS/CSS Minification and Bundling

# Merging CSS/JS
bin/magento config:set dev/css/merge_css_files 1
bin/magento config:set dev/js/merge_files 1

# Minification
bin/magento config:set dev/css/minify_files 1
bin/magento config:set dev/js/minify_files 1

# JS bundling (reduces HTTP requests)
bin/magento config:set dev/js/enable_js_bundling 1

Critical JS path—requirejs-config.js and default.js load synchronously. For FCP improvement use defer for non-critical modules via custom default_head_blocks.xml.

Result Measurement

# Before optimization
curl -o /dev/null -s -w "TTFB: %{time_starttransfer}s\nTotal: %{time_total}s\n" \
  https://myshop.ru/catalog/category/view/id/5

# After—typical result for properly configured Magento 2
# TTFB: 0.18s (page from Varnish)
# TTFB: 0.45s (PHP miss, Redis cache hit)

Timeline

PHP 8.2, OPcache, FPM pool, production mode, DI compile, static files: 1 day. MySQL tuning, Elasticsearch, flat catalog: 1–2 days. Varnish + Redis (cache + sessions): 2 days (separate pages). N+1 audit, indexers, CDN: 2–3 days. Total full optimization: 6–10 working days.