Skip to content
SK

APIs

GraphQL at Scale

Schema design, DataLoader patterns, and authorization strategies for production GraphQL APIs serving CRM and ecommerce dashboards.

2 min read·2026-02-10·Sachin Kaythamwar
graphql
apis
performance

GraphQL at Scale

GraphQL excels when clients need flexible data shapes — CRM dashboards pulling KPIs, ecommerce catalogs with nested variants, platform admin views aggregating cross-module data.

Schema Organization

Modular monoliths should mirror module boundaries in schema:

type Query {
  ...erpQueries
  ...crmQueries
  ...hrmsQueries
}

Each module owns its type definitions and resolvers. A schema merger composes the final API.

N+1 Prevention with DataLoader

The classic GraphQL performance trap. Batch and cache per-request:

const userLoader = new DataLoader(async (ids) => {
  const users = await userRepo.findByIds(ids);
  return ids.map(id => users.find(u => u.id === id));
});

Attach loaders to GraphQL context — one instance per request.

Authorization at Field Level

Don't rely on route-level auth alone. Field resolvers check permissions:

resolve: (parent, args, ctx) => {
  requirePermission(ctx.user, 'invoice:read');
  return invoiceRepo.findById(args.id);
}

Integrate with your RBAC module — consistent with REST middleware.

Pagination Patterns

Cursor-based pagination for large datasets (order lists, audit logs). Offset pagination only for small, stable result sets.

Caching Strategy

  • Redis for frequently accessed reference data (permissions, tenant config)
  • CDN/HTTP caching for public catalog queries where applicable
  • Avoid caching mutation responses

REST vs GraphQL Coexistence

Not everything needs GraphQL. Keep REST for webhooks, file uploads, and simple CRUD. Use GraphQL where client flexibility reduces over-fetching and round trips.

GraphQL at scale is an architecture discipline — not just a query language swap.