GraphQL Optimization
Techniques to solve the N+1 problem using Dataloader.
Skill by j4flmao
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/j4flmao-graphql-optimization
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: backend
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/graphql-optimization
What's inside
- Skill name
GraphQL Optimization- Description
- Techniques to solve the N+1 problem using Dataloader.
- License
- MIT
- Instructions
- 39 lines in SKILL.md · view on GitHub
Agent Skills spec issues
- name: only lowercase letters, digits and single hyphens allowed
- name: "GraphQL Optimization" does not match folder "graphql-optimization"
Files (1)
- SKILL.md
SKILL.md (first lines)
# GraphQL Optimization
## Purpose
GraphQL resolvers run per field, so a naive implementation issues one database query per parent object (N+1) and lets clients send arbitrarily expensive queries. This skill removes N+1 with batching, bounds query cost, and adds caching where it is safe.
## Agent Protocol
### Trigger
Exact user phrases: "graphql n+1", "dataloader", "graphql slow", "graphql performance", "batch resolvers", "query complexity", "depth limit", "persisted queries", "graphql caching".
### Input Context
- Server library (Apollo Server, GraphQL Yoga, Mercurius, graphql-java, Strawberry, gqlgen, Hot Chocolate).
- Data layer (SQL/ORM, REST backends) and the slow query or resolver.
- Whether the API is public (untrusted clients) or first-party only.
### Output Artifact
Loader definitions, context wiring, and server validation/caching config. No files unless requested.
### Response Format
```
Problem: {N+1 on Type.field | unbounded query | no caching}
Fix: {DataLoader keyed by X | depth<=N, complexity<=M | APQ/persisted | cache hint}
Queries before/after: {n} -> {m}
Code: {loader + resolver + server config}
```
## Diagnosing N+1
Enable SQL logging (or tracing via OpenTelemetry) and run a list query such as:
```graphql
{ posts(first: 50) { id title author { name } } }
```
51 queries (`SELECT posts` + 50 x `SELECT user WHERE id = ?`) is N+1. Target: 2 queries.
## DataLoader (Node.js)
Rules that make DataLoader correct:
1. **Create loaders per request** (in the context factory). A global loader caches across users and leaks data between requests.
2. The batch function receives an array of keys and **must return an array of the same length in the same order**, with `null` or an `Error` instance for missing keys.
3. Batching happens within one tick of the event loop; resolvers just call `loader.load(id)`.
```ts
import DataLoader from 'dataloader';
import type { Pool } from 'pg';
export interface User { id: string; name: string }
export function createLoaders(db: Pool) {
return {
userById: new DataLoader<string, User | null>(async (ids) => {
const { rows } = await db.query<User>(
'SELECT id, name FROM users WHERE id = ANY($1)',
[ids as string[]],
);
const byId = new Map(rows.map((u) => [u.id, u]));
return ids.map((id) => byId.get(id) ?? null);
}),
// One-to-many: key = authorId, value = that author's posts.
postsByAuthor: new DataLoader<string, Post[]>(async (authorIds) => {
const { rows } = await db.query<Post>(
'SELECT * FROM posts WHERE author_id = ANY($1)',
[authorIds as string[]],
);
const grouped = new Map<string, Post[]>();
for (const p of rows) {
const list = grouped.get(p.author_id) ?? [];
list.push(p);
grouped.set(p.author_id, list);
}
return authorIds.map((id) => grouped.get(id) ?? []);
}),
};
}
export interface Post { id: string; title: string; author_id: string }
```
Resolvers and per-request context (Apollo Server 4+ standalone):
```ts
import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';
import depthLimit from 'graphql-depth-limit';
import { Pool } from 'pg';
import { createLoaders } from './loaders';
import { typeDefs } from './schema'; // SDL string or DocumentNode
const db = new Pool({ connectionString: process.env.DATABASE_URL });
type Ctx = { loaders: ReturnType<typeof createLoaders> };
const resolvers = {
Post: {
author: (post: { author_id: string }, _: unknown, ctx: Ctx) =>
ctx.loaders.userById.load(post.author_id),
},
User: {
posts: (user: { id: string }, _: unknown, ctx: Ctx) =>
ctx.loaders.postsByAuthor.load(user.id),
},
};
const server = new ApolloServer<Ctx>({
typeDefs,
resolvers,
validationRules: [depthLimit(8)], // reject deeply nested queries
});
await startStandaloneServer(server, {
context: async () => ({ loaders: createLoaders(db) }), // fresh per request
});
```
Equivalents in other stacks: `java-dataloader` (graphql-java, Spring for GraphQL `@BatchMapping`), `strawberry.dataloader.DataLoader` (Python), `graph-gophers/dataloader` or gqlgen's dataloaden pattern (Go), Hot Chocolate `BatchDataLoader` (.NET).
## Alternative: Join-Based Resolution
When the parent resolver can see the selection set, fetch children in the same SQL with a JOIN (tools: Join Monster, PostGraphile, Hasura, Prisma `include`). This is faster for fixed shapes but couples resolvers to SQL; DataLoader stays simpler and works across data sources.From j4flmao/agent-skills, MIT.
More from j4flmao/agent-skills
- 0.610score
elysia-patterns
j4flmao
Use this skill when implementing Elysia.js patterns — Eden Treaty client, WebSocket handlers, auth/guard macros, custom plugins, performance optimization, and…
SkillBFreshness: B★ 34Claude Code +9 - 0.610score
dotnet-patterns
j4flmao
Use this skill when implementing .NET patterns — MediatR pipelines, CQRS, Result pattern, EF Core patterns, pipeline behaviors, and event sourcing.
SkillBFreshness: B★ 34Claude Code +9 - 0.607score
llm-finetuning
j4flmao
Best practices for dataset preparation and PEFT/LoRA fine-tuning.
SkillBFreshness: B★ 34Claude Code +9 - 0.607score
genai-vision
j4flmao
Integrating Stable Diffusion for vision generation and Whisper for audio/multimodal tasks.
SkillBFreshness: B★ 34Claude Code +9 - 0.605score
micronaut
j4flmao
Use this skill when building Micronaut applications — compile-time DI, reactive HTTP server, AOT optimization, GraalVM native image.
SkillBFreshness: B★ 34Claude Code +9 - 0.605score
bun
j4flmao
Use this skill when building with Bun runtime — Bun APIs, testing, package management, shell scripting, hot reload, SQLite, file I/O.
SkillBFreshness: B★ 34Claude Code +9 - 0.605score
elixir
j4flmao
Use this skill when building with Elixir — Phoenix framework, OTP, BEAM, LiveView, Ecto, supervision trees.
SkillBFreshness: B★ 34Claude Code +9 - 0.605score
deno
j4flmao
Use this skill when building with Deno — TypeScript runtime, Deno Deploy, Fresh framework, Deno std library.
SkillBFreshness: B★ 34Claude Code +9 - 0.601score
nestjs-architecture
j4flmao
Use this skill when structuring NestJS applications — module-based architecture, dependency injection, provider scopes, dynamic modules, and monorepo structure.
SkillBFreshness: B★ 34Claude Code +9 - 0.601score
kotlin-backend-patterns
j4flmao
Use this skill when implementing Kotlin backend patterns — repository pattern, service layer, DTO mapping, DI setup (Koin, Kodein), testing with MockK, and…
SkillBFreshness: B★ 34Claude Code +9 - 0.601score
kotlin-architecture
j4flmao
Use this skill when designing Kotlin backend architecture — Ktor, Spring WebFlux, http4k.
SkillBFreshness: B★ 34Claude Code +9 - 0.601score
nestjs-patterns
j4flmao
Use this skill when implementing NestJS patterns — CQRS with @nestjs/cqrs, guards/interceptors/pipes/filters, event sourcing, custom decorators…
SkillBFreshness: B★ 34Claude Code +9
Signals
- Stars
- 34
- Forks
- 4
- Open issues
- 0
- Last commit (this folder)
- Aug 30, 2026 (1 month ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/j4flmao/agent-skills
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from j4flmao
- 0.610score
dotnet-patterns
j4flmao
Use this skill when implementing .NET patterns — MediatR pipelines, CQRS, Result pattern, EF Core patterns, pipeline behaviors, and event sourcing.
SkillBFreshness: B★ 34Claude Code +9 - 0.610score
elysia-patterns
j4flmao
Use this skill when implementing Elysia.js patterns — Eden Treaty client, WebSocket handlers, auth/guard macros, custom plugins, performance optimization, and…
SkillBFreshness: B★ 34Claude Code +9 - 0.607score
genai-vision
j4flmao
Integrating Stable Diffusion for vision generation and Whisper for audio/multimodal tasks.
SkillBFreshness: B★ 34Claude Code +9 - 0.607score
llm-finetuning
j4flmao
Best practices for dataset preparation and PEFT/LoRA fine-tuning.
SkillBFreshness: B★ 34Claude Code +9 - 0.605score
bun
j4flmao
Use this skill when building with Bun runtime — Bun APIs, testing, package management, shell scripting, hot reload, SQLite, file I/O.
SkillBFreshness: B★ 34Claude Code +9 - 0.605score
deno
j4flmao
Use this skill when building with Deno — TypeScript runtime, Deno Deploy, Fresh framework, Deno std library.
SkillBFreshness: B★ 34Claude Code +9
Cite this page
GraphQL Optimization skill. Agent Mart. https://agentmart.dev/skills/j4flmao-graphql-optimization (last updated 2026-10-24)