ddtcorex

18 Jul 2026 · 2 min read

10 Magento 2 development mistakes that hurt performance

The recurring developer mistakes that quietly tank Magento 2 performance — from N+1 loads to plugin abuse and misconfigured caches — and how to avoid each.

Performance problems in Magento 2 rarely come from the platform itself. They come from small, repeated development decisions that compound. This post catalogs the ten we see most often — and the fix for each.

This series builds on the Magento 2 in practice intro, but stands on its own.

1. N+1 loads in collections

Loading a product, then looping and calling getX() that triggers another query per item. On a category page this becomes hundreds of queries.

Fix: use collection joins / addAttributeToSelect, eager-load relations once.

2. around plugins on hot paths

An around plugin wraps the original method and runs on every call — including product load in listings. Stack a few and TTFB climbs.

Fix: prefer before/after; use events when you don't need the return value.

3. Disabled or stale indexers

Leaving indexers on "Update on save" for large catalogs, or letting flat tables go stale, pushes read work into the request.

Fix: schedule indexers (or use the message queue); reindex before blaming the DB.

4. Cache disabled or misconfigured

Running with the full-page cache off, or with a leaky session cookie on every page, bypasses Varnish entirely.

Fix: verify FPC is on, sessions in Redis, and cacheable blocks aren't accidentally marked non-cacheable.

5. Loading the model when you need the resource

$product->load() inside a loop when a lightweight repository or collection query would do.

Fix: load collections, not entities, in bulk paths.

6. Heavy logic in templates (.phtml)

Business logic in templates runs on every render and can't be cached at the block level cleanly.

Fix: put logic in blocks/view models; keep templates presentational.

7. Over-fetching with GraphQL / REST

Requesting every field "just in case" in PWA/headless frontends balloons payloads.

Fix: query only the fields the view uses; batch where possible.

8. Unbounded result sets

->getItems() with no page size on large collections exhausts memory.

Fix: paginate; cap with setPageSize.

9. Ignoring the profiler

Shipping without ever looking at where time goes.

Fix: capture a profiler trace (the stock CSV profiler works well) and read it before optimizing blind.

10. Treating local as production

A dev machine with opcache off and no Varnish hides every caching win — then production surprises you.

Fix: run a production-shaped stack locally. A framework-aware orchestrator like Govard wires Varnish + Redis + OpenSearch so your local environment matches what you'll actually ship.

What's next in this series

We've named the mistakes; now the positive checklist. Next: the performance best practices that move the needle most.

Next in this series: Magento 2 performance best practices — /blog/magento2-performance-best-practices

magento2performancebest-practices