Back to all terms
ClientAPIrequestresponseheaders
APIadvanced

GraphQL N+1 (DataLoader)

A batching and caching strategy using DataLoader to solve the N+1 query problem inherent in naive GraphQL resolver implementations.

Also known as: DataLoader Pattern, Batched Data Fetching, N+1 Query Problem

Description

The N+1 problem in GraphQL occurs when a resolver for a list field triggers one query to fetch the list (1) and then an additional query for each item to resolve a nested field (N), resulting in N+1 total queries. For example, fetching 50 orders and their associated customers would naively execute 1 query for orders plus 50 individual queries for customers. DataLoader, originally created at Facebook, solves this by batching and deduplicating these individual loads into a single bulk query per tick of the event loop.

DataLoader works by collecting all keys requested during a single tick of the event loop and then calling a batch function once with all collected keys. The batch function must return results in the same order as the input keys, and DataLoader handles distributing the results back to the individual callers. Within a single request, DataLoader also caches results by key, so if the same customer ID is referenced by multiple orders, the database is queried only once.

DataLoader instances must be created per-request (not globally) to avoid leaking cached data between different users or requests. They are typically instantiated in the context factory and passed through the resolver context. The batch function should use an IN clause or equivalent bulk-fetch operation (e.g., SELECT * FROM customers WHERE id = ANY($1)) to retrieve all requested records in a single database round trip.

Prompt Snippet

Create a new DataLoader instance per request in the GraphQL context factory to prevent cross-request cache contamination. Implement batch functions using SQL IN clauses (SELECT * FROM customers WHERE id = ANY($1::uuid[])) and ensure results are returned in the same order as input keys by building a Map and mapping over the keys array. Set maxBatchSize to 100 to prevent oversized IN clauses. Monitor batch efficiency by logging batch sizes and comparing total DataLoader loads vs actual DB queries per request in the resolver tracing output.

Tags

graphqlperformancedataloadern-plus-1batching