30 Drupal & Commerce Performance Tips At the Config Level (2026)

These tips address pain points with cart sessions, order processing, product queries, cache invalidation, and hidden writes.

Note: Most tips require server access (php.ini, nginx.conf, my.cnf, Redis config). They shine on VPS/dedicated hosting. Test changes in staging and monitor with tools like New Relic, Blackfire, or slowlog.

Drupal Commerce Internals

Tip #1: Cart fragments / AJAX on every page
Drupal Commerce often fires cart-related AJAX or rebuilds on every request (especially with blocks or mini-cart). Disable unnecessary cart refresh for non-shop pages via a custom module or hook_page_attachments_alter().

Tip #2: Redis evicting active carts/sessions
Use the Redis module (or core cache backend) and set:

maxmemory-policy volatile-lru

Monitor: redis-cli INFO stats | grep evicted_keys. This protects customer carts while allowing natural expiration.

Tip #3: High-frequency order writes
Commerce uses dedicated tables for orders/variations. Avoid double-writing by ensuring you use the latest storage handlers and minimize post-save hooks on every order update. Review custom code for unnecessary entity saves.

Tip #4: Stale product data / indexes
Commerce stores data in commerce_product / field tables. After bulk imports or ERP syncs, clear caches and re-index with Drush: drush search-api:clear (if using Search API) or drush cache:rebuild. Regenerate any denormalized views/tables manually.

Tip #5: Hidden database writes on every request
Modules often write to cache/config on page loads (analytics, trackers). Use $databases['default']['default']['init_commands'][] = 'SET SESSION sql_mode=""'; + enable slow query log to spot them. Move non-critical writes to cron.

Database & MariaDB

Tip #6: Bloated cache/config data
Drupal loads significant config on bootstrap. Query:

SELECT SUM(LENGTH(value)) FROM cache_config WHERE cid LIKE '%system%';

(or check config table). Clean stale config with drush config:delete or drush cache:rebuild.

Tip #7: Disable query cache
In my.cnf:

query_cache_type = 0
query_cache_size = 0

Commerce writes (stock, orders, carts) invalidate it constantly, causing mutex locks. Restart MariaDB.

Tip #8: InnoDB buffer pool

innodb_buffer_pool_size = 70% of RAM (dedicated) or ~40% (shared VPS)

Check hit ratio:

SHOW STATUS LIKE 'Innodb_buffer_pool_read%';

Aim for <1% disk reads. Critical for product/variation queries.

Tip #9: Payment gateway transients / cache bloat
Query for gateway cache rows (e.g., Stripe/PayPal modules store in cache bins or key_value). Truncate old entries and ensure expiration is set.

Tip #10: Sessions table / Redis bloat

SELECT COUNT(*) FROM sessions;

Clean: DELETE FROM sessions WHERE timestamp < UNIX_TIMESTAMP() - 86400;. Prefer Redis for sessions with proper TTLs.

Tip #11: Queue / Action bloat
Commerce + core Queue API grows. Use Advanced Queue or set retention low. Purge old items via Drush/cron after 1 day.

Tip #12: Missing indexes on fields
Commerce variations/prices/stock live in field tables. Run EXPLAIN on slow queries and add:

ALTER TABLE commerce_product_variation_field_data ADD INDEX idx_sku (sku);

(or on price/stock columns). Adapt to your custom fields.

Tip #13: tmp_table_size for reports

tmp_table_size = 64M
max_heap_table_size = 64M

Monitor Created_tmp_disk_tables. Essential for Views, order reports, and aggregates.

PHP & PHP-FPM

Tip #14: PHP-FPM slow-log
In pool config (www.conf):

slowlog = /var/log/php-fpm-slow.log
request_slowlog_timeout = 3s

Captures long Commerce checkouts, payment hooks, or entity loads.

Tip #15: OPcache interned strings

opcache.interned_strings_buffer=64

Check: php -r "print_r(opcache_get_status(true));". Drupal 10’s Twig + entity system benefits hugely.

Tip #16: pm.max_children math
Formula: (Total RAM – OS – MariaDB – Redis) / avg worker RSS.
Measure: ps --no-headers -o rss -C php-fpm | awk '{sum+=$1} END {print sum/NR/1024"MB"}'. Typical 40–80MB per worker.

Tip #17: Shutdown hooks
Slow-log reveals analytics/payment modules holding workers post-response. Refactor to queues.

Tip #18: pm = static or ondemand
High traffic → static. Spiky → ondemand. Never dynamic for e-commerce.

Nginx & Caching

Tip #19: fastcgi_cache cart bypass

if ($cookie_commerce_cart) { set $skip_cache 1; }  # adapt to your actual cart cookie
fastcgi_cache_bypass $skip_cache;

Prevent stale cart display.

Tip #20: Upstream keepalive

upstream php {
    server unix:/var/run/php-fpm.sock;
    keepalive 16;
}
# In location:
proxy_http_version 1.1;
proxy_set_header Connection "";

Tip #21: Smart PURGE
Use Purge module + cache tags. Purge only affected product/order URLs + homepage on stock changes, not the entire site.

Tip #22: stale-while-revalidate

fastcgi_cache_use_stale updating;
fastcgi_cache_background_update on;
Prevents stampedes on popular product pages.

Tip #23: open_file_cache

open_file_cache max=10000 inactive=60s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;

Saves syscalls on Twig templates and assets.

Redis & Object Cache

Tip #24: Cache invalidation from writes
Hidden cache::set() or config saves on every request kill hit ratios. Use drush watchdog:show + query logging to find offenders.

Tip #25: Redis memory sizing
Set maxmemory to 2× typical usage. Check: redis-cli INFO memory. Account for cache bins, tags, sessions, and product data. Use volatile-lru.

Drupal & Server

Tip #26: System cron (disable internal)
In settings.php:

$settings['cron']['disable'] = TRUE;

Crontab: */5 * * * * drush cron (or wget the cron URL with key). Eliminates loopback on every request.

Tip #27: Heavy entity queries in admin
Use Views with proper indexes or Search API. Avoid unoptimized hook_entity_query_alter() without checks.

Tip #28: Loopback requests
Beyond cron: payment webhooks, module updates. Ensure the server can resolve its own domain quickly or use internal IPs.

Tip #29 & #30: Hidden writes & cache thrashing
Enable query logging in settings.php and hunt UPDATE/INSERT on cache/config tables. Combine with Redis proper eviction policy.

Quick-Start Implementation Order

  1. MariaDB buffer pool + query cache off.
  2. PHP-FPM tuning + slow-log.
  3. Redis volatile-lru + cart bypass.
  4. System cron + cache tags.
  5. Nginx keepalive + open_file_cache.

These routinely deliver 2–5× improvements on Commerce sites. Many are one-line config changes with outsized impact.