Overview
As developers, we aim to build performant applications that scale with our users and data, without sacrificing development speed. Apollo Connectors help us move fast by reusing existing APIs within our reach. Working within our GraphQL schema, we define requests to data sources and map their responses to our types and fields.
But sometimes, even with clean code and good intentions, performance issues can sneak in unnoticed!
In this course, we'll shine a spotlight on one of those sneaky performance bottlenecks: the N+1 problem. This issue isn't exclusive to GraphQL or Connectors! It can show up in other data-fetching scenarios, whether we're calling REST API endpoints or running database queries.
In this lesson, we'll learn what the N+1 problem is, how it impacts performance, and how batching solves it.
One request leads to N more
Here's what we mean by the N+1 problem. We start with an initial request (the 1 in the N+1 equation) that then triggers multiple follow-up requests (the N). We don't know the number of follow-up requests, N, until the first request is executed.
Requests from the client to REST APIs
Let's consider a storefront page that displays a list of orders, where each order includes details about the customer who submitted it.
For an application using REST APIs, the client would need to:
- Send one request to fetch the most recent list of orders, which could include anywhere from 1 to 10 orders.
- When the response arrives, the client now has up to 10 unique
userId
values. This is the N number of follow-up requests. - The client sends 10 additional requests—one for each
userId
—to fetch the corresponding customer data. - After receiving these 10 responses, the client stitches the data together for display.
That's 11 total network requests to load a single page!
As the number of orders increases, so does the number of user data requests. This is the N+1 problem in action. While a few extra requests might seem manageable, this pattern can lead to significant performance slowdowns as queries scale—resulting in higher costs and slower user experiences.
All of those steps that the client needs to do? That's API orchestration. Orchestrating API calls efficiently is a constant challenge in app development; we typically handle it by writing a lot of procedural code. With the declarative approach of Apollo Connectors, we can speed up that process.
Requests from the client with the help of GraphQL & Apollo Connectors
Let's take the same example with the storefront page displaying the most recent orders. This time, we'll use GraphQL, where the query might look something like this:
query GetRecentOrders {recentOrders {idstatussubmittedAtuser {namelocation}}}
To retrieve that data, the client would need to send just one request containing the query above. No need to wait for the response, make follow-up requests, and stitch all that data together. Everything is handled smoothly (and much more quickly!) on the server side.
With the GraphQL approach, we've shifted the responsibility of the data fetching logic over to the server. This is all defined declaratively in the schema using Apollo Connectors. But it doesn't automatically solve the N+1 problem for us. We need to make sure our Connectors are set up correctly to enable batching.
Batching to the rescue
To solve the N+1 problem, we use batching: a technique that combines many similar requests into a single request.
Instead of fetching users one ID at a time, batching lets us ask for all the users we need information about, all in one go.
If you've worked with GraphQL servers before, then you'll recognize batching as the job of a data loader. You'd create a data loader class, implement the loading method, then update the resolver function to use the data loader.
With Apollo Connectors, it's simpler: we keep our work in the schema and use a variable called $batch
combined with a REST API batch endpoint. We'll explore this in more detail later on in the course.
Learner pre-requisites
We assume that you're familiar with the basics of a GraphQL schema and how to send GraphQL operations. Check out graphql.com/learn if you need a refresher. You don't need to know any particular programming language for this course.
It would also be helpful to be familiar with the basics of Apollo Connectors. Check out "GraphQL meets REST, with Apollo Connectors" for an overview.
Practice
Key takeaways
- The N+1 problem is a performance issue where one request leads to N additional and often unexpected requests, resulting in slow response times.
- Batching is the solution to the N+1 problem: replacing multiple requests by combining them into a single batched request.
Up next
Hands on the keyboard time! Next up, we'll get our project set up so we can see N+1 and batching in Connectors in action.
Share your questions and comments about this lesson
This course is currently in
You'll need a GitHub account to post below. Don't have one? Post in our Odyssey forum instead.