N+1 API Calls

An N+1 API Calls issue is created when your application calls the same endpoint many times in quick succession, usually once for every item in a list, instead of asking for all of them in a single call.

It is the same pattern as an N+1 DB Query, applied to HTTP calls. Each call has its own overhead: opening a connection, sending the request, waiting for the response. Doing that dozens of times adds up. It also puts more load on the service being called, which has to handle a burst of small requests instead of one larger one.

This issue is found in APM and RUM. In APM, one service makes the repeated calls to another. In RUM, a page in the browser makes them to your backend.

How Middleware detects it#

Middleware looks at the outgoing requests made within one operation. It flags a group of calls when many requests to the same endpoint, each asking for a different item, are made close together and add up to a noticeable amount of time.

What you'll see in Middleware#

An N+1 API Calls issue in the OpsAI issue list

The title shows the request, the number of times it was repeated, and the operation that made the calls, for example GET /products/{id} (15× in /catalog). Open the issue to see the calls and how much time they added.

Common causes#

  • A list view that loads details item by item. The page fetches a list of ids, then requests each item separately.
  • Fetching related data in a loop. For each result, call another service for its owner, price, or status.
  • A backend that only offers single-item endpoints, so the client has no way to ask for many at once.
  • Components that each fetch their own data on a page that shows many of them.

How to fix it#

  1. Add or use a batch endpoint. Let the caller send a list of ids and receive all the results in one response.
  2. Include the data in the list response. If every list item needs the same extra details, return them with the list.
  3. Fetch in one place. On the frontend, collect what the page needs and request it together, instead of letting each component fetch its own data.
  4. Cache what doesn't change. If the same items are requested often, cache them so repeat requests don't hit the service.
  5. If you can't change the API, at least run the calls in parallel and limit how many run at once, so they don't overwhelm the service.

Example#

A catalog page shows 20 products. It first requests the list of product ids, then makes a separate request for each product to get its name and price. That's 21 requests to render one page, and on a slow mobile connection the page fills in one row at a time.

After adding an endpoint that returns the details for a whole list of products in one response, the page makes two requests instead of 21. The N+1 API Calls issue stops receiving new occurrences.

Need assistance or want to learn more about Middleware? Get in touch with us via our Contact Us or join our Slack channel.