GraphQL vs REST — N+1 Query That Took Down a Product Page
When a GraphQL product page slowed from 200ms to 8 seconds due to N+1 queries, the DataLoader fix proved crucial—and REST avoids the problem entirely.
- REST organizes APIs around resources and HTTP verbs — predictable, cacheable, and universal.
- GraphQL lets clients declare exact data shapes — solves overfetching and underfetching but adds complexity.
- Choose REST when you have few clients, simple CRUD, or need aggressive HTTP caching.
- Choose GraphQL for multiple client types, rapid iteration, or mobile-heavy apps.
- The hybrid pattern — GraphQL at the edge, REST internally — is what senior teams actually run in production.
Imagine you're at a restaurant. With REST, there's a fixed menu — you order the 'burger meal' and you get a burger, fries, AND a drink, even if you only wanted the burger. With GraphQL, you tell the waiter exactly what you want: 'just the burger, no fries, add extra cheese.' REST gives you predefined plates; GraphQL lets you build your own plate every time. Neither is wrong — it just depends on whether your customers always want the same thing.
Every modern app lives or dies by its API. Whether you're building a mobile app that has to load fast on a 3G connection in rural Brazil, or a dashboard that needs to stitch together data from five different services, the API architecture you choose on day one will haunt you — or reward you — for years. GraphQL and REST are the two dominant players in that space, and the choice between them is one of the most hotly debated decisions in backend engineering.
REST has been the industry standard for over two decades. It's predictable, HTTP-native, and every developer on earth has used it. But as UIs grew more complex and mobile clients became first-class citizens, REST started showing its cracks. Teams were hitting endpoints and getting mountains of data they didn't need, or worse, firing off six requests just to render a single screen. GraphQL was Facebook's answer to that pain, built internally in 2012 and open-sourced in 2015.
By the end of this article you'll be able to clearly explain the structural difference between REST and GraphQL, identify the specific scenarios where each one wins, spot the classic mistakes teams make when choosing between them, and walk into a system design interview with a confident, nuanced answer instead of a vague 'it depends.'
How REST Actually Works — and Where It Starts to Break
REST (Representational State Transfer) organizes your API around resources. A resource is a noun — a User, an Order, a Product. You expose that resource at a URL, and HTTP verbs tell the server what to do with it: GET to read, POST to create, PUT/PATCH to update, DELETE to remove. This mapping is clean, intuitive, and stateless by design.
The trouble starts when your UI needs don't map neatly onto individual resources. Say you're building a Twitter-style profile page. You need the user's name and avatar, their last three tweets, and their follower count. In REST, that's three separate endpoints: GET /users/:id, GET /users/:id/tweets, GET /users/:id/followers. Three round trips. On mobile, each round trip is expensive.
The other side of that coin is overfetching. GET /users/:id might return 40 fields — date of birth, billing address, preferences, internal flags — when your profile page only needs four of them. You're downloading data you'll throw away, every single time.
These two problems — underfetching (too few fields, too many requests) and overfetching (too many fields, wasted bandwidth) — are not bugs in REST. They're structural consequences of organizing an API around fixed resource shapes instead of around what the client actually needs.
How GraphQL Solves Overfetching — and the Trade-offs It Introduces
GraphQL flips the model on its head. Instead of the server deciding what data a response contains, the client declares exactly what it needs in a query. The server exposes a single endpoint (typically POST /graphql) and a typed schema that describes every piece of data available. The client sends a query document describing the shape it wants, and the server returns exactly that shape — nothing more, nothing less.
That same profile page that needed three REST requests? One GraphQL query handles it. The client asks for user name, avatar, their last three tweets, and follower count in a single request. The server resolves all of it and returns one response shaped exactly like the query.
But GraphQL isn't a free lunch. That flexibility comes with real costs. Caching gets harder — REST leverages HTTP caching at the URL level natively, while GraphQL's single endpoint makes URL-based caching useless by default (you need tools like Apollo Client's normalized cache or persisted queries). Query complexity is another concern: a malicious or poorly-written client can craft a deeply nested query that brings your database to its knees. You need query depth limiting and complexity analysis in production. The learning curve for schema design and resolvers is also steeper than standing up REST routes.
Real-World Decision Framework — When to Actually Pick Each One
The honest answer isn't 'GraphQL is better' or 'REST is simpler.' The right answer depends on the shape of your problem. Here's how senior engineers actually think about this decision.
Choose REST when your data model is simple and resource-oriented, your clients are few and controlled (e.g., internal services talking to each other), you need aggressive HTTP caching (CDN caching of GET endpoints is trivially easy with REST), or your team is small and you want zero-overhead tooling. Public APIs that third-party developers will consume are also often better served by REST — it's more universally understood and doesn't require GraphQL client libraries.
Choose GraphQL when you have multiple client types with different data needs — a mobile app, a web app, and a third-party integration all hitting the same backend. It's the perfect fit for a BFF (Backend for Frontend) layer. Also choose it when your product is iteration-heavy: adding a new field to a GraphQL schema is non-breaking by default, whereas adding a new REST endpoint requires versioning discussions. Rapid product teams love this.
The hybrid approach is increasingly common: REST for simple CRUD microservices talking to each other, GraphQL at the edge as an API gateway that stitches them together for clients. This is the architecture used by major platforms like GitHub (which offers both APIs) and Shopify.
The Hybrid Architecture — GraphQL Gateway + REST Microservices
You don't have to pick one. The most mature production architectures use both: REST between internal microservices and GraphQL at the edge. Here's why that pattern wins.
Internal services talk to each other over REST (or gRPC). These calls are simple, cacheable at the service proxy level, and don't benefit from GraphQL's flexibility because each service has exactly one consumer. Adding GraphQL between internal services adds schema overhead and latency with no payoff.
At the edge, a GraphQL gateway sits between your clients and your internal services. The gateway resolves queries by making REST calls to the backend services. Clients get the benefits of GraphQL — declarative data fetching, reduced overfetching, single round trip — while your internal architecture stays simple and decoupled.
This pattern is what GitHub, Shopify, and Netflix run in production. GitHub's v4 GraphQL API is a gateway that aggregates data from over 200 internal REST services. Clients never know. They just send a query and get back exactly what they need.
Production Considerations — Caching, Security, Monitoring
Both REST and GraphQL have production pitfalls that you won't find in tutorials. Here's what actually matters when your API is handling millions of requests.
Caching is the biggest practical difference. REST endpoints are trivially cacheable at the CDN layer because each URL is unique. CDNs can cache GET /users/42 for 300 seconds and serve the cached copy to the next thousand requests. GraphQL's single endpoint means every request is a POST with a different query body — CDN caching is useless unless you use persisted queries (where each query has a unique hash ID). If your team cares about CDN cache hit rates, REST wins hands down.
Security: REST benefits from the full HTTP security toolkit — rate limiting by URL, WAF rules per path, IP allowlisting per resource. GraphQL requires you to implement depth limiting, query cost analysis, and allowlisting of known operations. Without these, a single malicious query can DDoS your entire API.
Monitoring: REST’s HTTP status codes map cleanly to error budgets and alerting — 5xx rate goes up, pager goes off. GraphQL returns 200 even for partial failures, so your monitoring must parse response bodies for errors. Most teams miss this and only realize after an incident that their error rate looked fine while users were seeing partial data.
Neither architecture is more secure or more observable by nature — they just require different tooling. The team that plans for these differences will sleep better at night.
The N+1 Query That Took Down a Product Page at 2 PM
- Any resolver that fetches a list of related entities (reviews per product, tweets per user) is a candidate for the N+1 problem.
- Never ship a GraphQL resolver that does a single DB call per parent item without batching.
- Add query depth limiting (max 5 levels) and complexity analysis to every production GraphQL server.
Key takeaways
Common mistakes to avoid
5 patternsUsing GraphQL for microservice-to-microservice communication
Ignoring the N+1 query problem in GraphQL resolvers
Assuming REST endpoints always need versioning
Not implementing query depth limits or cost analysis on GraphQL
Treating GraphQL error handling like REST error handling
Interview Questions on This Topic
You're designing the API layer for an e-commerce platform with an iOS app, an Android app, a web storefront, and a third-party affiliate integration. Each client needs different subsets of product data. Walk me through how you'd decide between REST and GraphQL, and what architecture you'd land on.
Frequently Asked Questions
That's Architecture. Mark it forged?
6 min read · try the examples if you haven't