A Magento developer swapped 300 separate ProductRepositoryInterface::getById() calls for a single collection query. The database hits dropped from 300 to 1, and the category page loaded noticeably faster. The trade-off? Some products vanished from the storefront, baffling shoppers and owners.

The N+1 problem on a Magento category page

The page listed 300 products. For each one the code fetched two custom attributes via the repository’s getById() method, generating one query per product—the classic N+1 pattern. Replacing those per-product loads with a collection that pulls all needed rows in one query slashed the query count. Front-end latency improved, but the product list now missed items that had previously appeared.

Why the collection hides out-of-stock items

Magento’s CatalogInventory module automatically adds an “in-stock” filter to any product collection built for the frontend. The filter activates when the store setting Display Out of Stock Products is turned off, a common choice for merchants who don’t want to show unavailable items.

By contrast, the repository never applies a stock filter. It simply checks that a product exists and returns it, regardless of inventory level. When the code switched from repository calls to a collection, the stock filter silently stripped every product whose quantity was zero. No error logged; the collection just returned fewer rows than the developer expected.

What this means for merchants

A storefront that silently drops out-of-stock SKUs creates several problems:

  • Front-end components receive missing entries, producing empty labels or wrong pricing.
  • Debugging becomes harder because the symptom—missing products—does not generate warnings.

Because most automated tests use in-stock fixtures, the bug often stays hidden until the site runs with real inventory.

How to keep speed without hiding inventory

  1. Skip the default stock filter – Explicitly remove the filter from the collection if you need every product regardless of availability. Magento offers methods to disable or replace the stock plugin per query.
  2. Use the repository when accuracy matters – The repository guarantees that every requested product ID is returned, even if it’s out of stock. Cache the results or load only the IDs you need to tame the extra queries.
  3. Employ a resource model or raw SQL – Query the product table directly for the required attributes. This bypasses all collection plugins and gives you full control over which rows are included.

Speed versus correctness

Swapping a noisy N+1 loop for a single collection query feels natural; the latency drop is tangible. Yet a faster query that returns the wrong set of products is a defect, not an optimization. Developers must weigh raw speed against the risk of showing an incomplete catalog.

What to watch for next

  • Configuration drift – Verify that the Display Out of Stock Products flag matches the intended behavior of any custom collection code.
  • Plugin side effects – Other modules may add their own filters to collections. Review the plugin stack whenever you change query strategies.

The lesson is clear: fixing an N+1 issue with a collection wins only if you also audit the collection’s default filters. Ignoring Magento’s built-in stock filter can silently prune your catalog, turning a performance gain into a revenue loss.