GraphQL Schema, Federation & Performance Design

Design and fix GraphQL schemas, DataLoader resolvers, federation, and subscriptions without N+1 or breaking changes.

Development / Backendgraphqlapollo-federation
by AgentVoltv1.0.0
Free to sign up · every skill included with AgentVolt Pro

Before & after

Same prompt, same agent — the only difference is the skill.

Prompt“My GraphQL API is slow — users query nested and it falls over.”
Beforegeneric AI agent
Slow nested GraphQL queries usually point to the N+1 problem. When you query a list of items and each one resolves a nested field, you end up making one database query per item.

Some solutions to consider:
- Use DataLoader to batch and cache database calls within a request
- Implement query depth limiting to prevent deeply nested queries
- Add pagination to list fields
- Consider query complexity analysis to reject expensive queries
- Look into caching at the resolver level

DataLoader is probably the most impactful change. It batches individual loads that occur within a single tick of the event loop.

Would you like help implementing any of these?
Afterwith GraphQL Schema, Federation & Performance Design
That's N+1. Here's the fix in the order that matters.

THE SHAPE OF THE PROBLEM
  query { posts(first: 50) { author { name } } }
  → 1 query for posts, then 50 for authors. 51 round trips for 50 rows.

1 — DATALOADER (does ~90% of the work)
  loaders/userLoader.js
    new DataLoader(async (ids) => {
      const rows = await db.user.findMany({ where: { id: { in: ids } } })
      const byId = new Map(rows.map(r => [r.id, r]))
      return ids.map(id => byId.get(id) ?? null)   // MUST return in input order
    })

  Two rules people get wrong:
  • Construct per request, in context — a module-level loader caches across
    users and leaks data between them.
  • The batch fn must return results positionally, same length as keys.
    Returning the raw DB rows silently mismatches when a row is missing.

  51 queries → 2.

2 — DEPTH LIMIT — stop the pathological query, don't just make it fast
  depthLimit(7) in validationRules. A client can nest
  author→posts→author→posts forever; DataLoader makes that efficient, not
  bounded.

3 — COMPLEXITY SCORING
  Cost per field, reject over budget. first: 1000 on three nested
  connections passes a depth limit and still melts the DB.

4 — CONNECTION PAGINATION on every list field
  Unbounded lists are the thing depth limits can't save you from.

IF YOU'RE FEDERATED
  Each subgraph needs its own loaders — the gateway batches entity
  resolution across subgraphs, but not within one. A @key reference
  resolver without a loader is the same N+1, one layer down.

Start with #1 and re-measure before doing the rest.

About this skill

Your GraphQL endpoint started fast and now a single orders query fires 400 database calls, one failing field blanks the whole response, and nobody knows if removing a field will break the mobile app. This skill designs and repairs GraphQL APIs the way a practitioner who has run them in production would, with concrete SDL, resolver code, and migration steps.

What it does

  • Designs schemas around client use cases: action-named mutations, input/payload types with typed user errors, and nullability chosen deliberately so one downstream failure does not null out an entire query
  • Finds and kills N+1 patterns with per-request DataLoaders, including the hard cases: one-to-many relations, paginated children per parent, and composite keys
  • Plans Apollo Federation 2 subgraph boundaries, @key entities, batched reference resolvers, @requires/@shareable/@override usage, and safe field migration between subgraphs
  • Adds production guardrails: cost and depth limits that account for list multipliers, trusted documents, alias and batching abuse limits, and error masking
  • Designs subscriptions with the right transport, a multi-instance pub/sub backend, per-event authorization, and reconnect behavior
  • Classifies proposed schema changes as safe, dangerous, or breaking, and writes the deprecation-to-removal path

What you get

A right-sized answer: for a quick question, a direct fix; for a design or review, SDL, resolver and loader code, a ranked risk list, and an ordered rollout plan with assumptions stated up front.

Best for

Backend and full-stack engineers building or maintaining GraphQL APIs on Apollo Server, Apollo Router, or similar stacks, especially teams moving from a monolithic graph to federation or fighting performance problems under load.

SKILL.md preview

SKILL.md
---
name: graphql-schema-federation-performance
description: Designs, reviews, and repairs GraphQL APIs - schema and nullability design, DataLoader batching for N+1, cursor pagination, Apollo Federation 2 subgraph boundaries, query cost limits, and subscriptions - delivering SDL, resolver code, and an ordered rollout plan. Use when the user says "design a GraphQL schema for...", "our GraphQL query times out under load", "my resolvers keep hitting the database hundreds of times", "split our graph into subgraphs with Apollo Federation", "add real-time subscriptions", "review this schema", "is removing this field a breaking change", or "one error wipes out the whole response".
---

… (sign up to view the full skill)
Sign up to view, copy, and install the full skill

More development skills

View all Development skills →