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 = 0Commerce 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 = 64MMonitor 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 = 3sCaptures long Commerce checkouts, payment hooks, or entity loads.
Tip #15: OPcache interned strings
opcache.interned_strings_buffer=64Check: 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
- MariaDB buffer pool + query cache off.
- PHP-FPM tuning + slow-log.
- Redis
volatile-lru+ cart bypass. - System cron + cache tags.
- Nginx keepalive + open_file_cache.
These routinely deliver 2–5× improvements on Commerce sites. Many are one-line config changes with outsized impact.