The N+1 query problem
A list of fifty orders, each resolving its customer and items separately, turning one request into hundreds of database queries.
[ Development ]
One flexible endpoint, without the surprise bills.
GraphQL gives front-end teams exactly the data they ask for. Without care it also gives anyone on the internet a way to write one query that makes four thousand database calls. I design schemas that are pleasant to consume and servers that stay fast, authorized and bounded when clients get creative.
Schema-first · N+1 handled from day one · Fixed scope
[ What goes wrong ]
Usually not on launch day. Once the schema has grown and clients start composing queries nobody planned for.
A list of fifty orders, each resolving its customer and items separately, turning one request into hundreds of database queries.
The login check happens at the query root, but nested fields happily return another customer's data through a relationship.
No depth, complexity or pagination limits, so one deeply nested query — accidental or malicious — can take the API down.
Tables exposed one-to-one as types, so every internal column rename becomes a breaking change for every client.
Errors hidden inside successful responses, so monitoring shows a healthy API while users see broken screens.
Fields removed or retyped without deprecation, and mobile apps still in users' pockets start failing.
[ How it works ]
Types, queries and mutations designed with the teams that will consume them, before resolvers exist. You get the draft schema, a written scope and a fixed price.
Resolvers with batching, authorization and validation built in, tested against real queries and shipped in reviewable pull requests to staging.
Depth and cost limits, persisted queries where they fit, tracing per resolver, and schema checks in CI so breaking changes are caught before merge.
[ What actually changes ]
Framework chosen to fit your stack. The patterns that keep it fast and safe are the same everywhere.
[ Example engagement ]
A GraphQL API where the main dashboard query triggered several hundred database calls. DataLoader batching, one missing index and query cost limits added.
Illustrative example of a typical engagement. Figures vary with the state of your systems and are not a guarantee of a specific outcome.
[ Free · no obligation ]
Describe what the API serves, or the query that is slow. You get a written scope and a fixed price — not a sequence of discovery calls.
[ Pricing ]
Tell me the number you have to work with. I'll tell you honestly what's achievable within it — and if it isn't enough, I'll say so before we start rather than halfway through.
Hourly rate $20/hoursmall jobs and ongoing work · fixed price for defined projects
Scope agreed in writing, price agreed in writing, before any work starts. No hourly creep and no invoice you haven't already approved.
For ongoing work — maintenance, monitoring, updates and small changes. Month to month, cancel whenever, no minimum term.
For a single bug, a short task or ongoing tweaks, where writing a full scope would cost more than simply doing the work. Billed in real time, reported in writing.
Budget too tight for the whole thing? I'll often suggest doing the highest-value part first and the rest later, rather than doing all of it badly.
[ Questions ]
Small or hourly work — fixing an N+1 problem, reviewing a schema, adding query limits — is billed at $20 per hour. A defined build or migration gets a fixed price agreed in writing before I start, so the number does not change halfway through.
GraphQL earns its keep when several clients — web, mobile, partners — need different shapes of the same data, or when the front end keeps waiting for new endpoints. For a simple public API or file-heavy endpoints, REST is often simpler and easier to cache. I will tell you which fits.
Whatever matches your stack. Apollo Server or GraphQL Yoga on Node.js, Lighthouse for Laravel, Strawberry for Python, and Hasura when you want an instant API over PostgreSQL with permissions defined declaratively.
DataLoader or its equivalent from the first resolver, so related records are batched into one query per type per request. Then I check the actual SQL a real query produces, because batching only helps if the underlying queries are indexed.
Authorization checked at field level, query depth and cost limits, pagination caps, introspection disabled or restricted in production, and persisted queries for first-party clients so arbitrary operations are not accepted at all.
Yes, and that is usually the right approach. A GraphQL layer can sit in front of your existing REST services, so clients switch over screen by screen while the backend is moved behind it at whatever pace makes sense.
Only if several teams or services genuinely own separate parts of the graph. For a single team, one well-organized schema is simpler to build, test and operate. Federation solves an organizational problem, and it has a real operational cost.
Yes. I design the schema with the people who will consume it, set up generated types for Apollo Client, urql or Relay, and add schema checks to CI so neither side breaks the other. I work remotely with teams in the US, UK, Europe, Canada and Australia.
[ Related services ]
[ Let's talk ]
Describe it in a few lines and you'll get a straight answer on scope, cost and timeline — from the person who would actually build it.