AI-Powered Automated GraphQL Schema Cleanup
whatnot · E-commerce · 2025 · source Agentic: yes · promotional bias: med · source-backed · extracted with prompt 0.5.4 (schema v2)
Generated from extraction.json — do not edit by hand. Every claim cites verbatim source evidence; stated means the quote directly asserts the claim, implied means it supports it indirectly.
Problem
Domain: GraphQL schema maintenance
Whatnot needed to remove unused GraphQL fields safely across multiple clients without asking engineers to spend hours manually tracing each field and cleanup path.
Constraints:
- iOS, Android, web, and admin clients
- older mobile app versions
- traffic-based safety requirements
- code-owner review
- risk of breaking production clients
Architecture
Whatnot turned GraphQL cleanup into a traffic-evidence pipeline: real query logs and schema traversal identify unused fields, a daily GitHub Action asks an AI agent to remove one field, and PRs carry validation data plus code-owner review.
Diagram confidence: reconstructed (reconstructed from prose).
flowchart LR graphql-traffic-logs["GraphQL traffic logs"] schema-ast-traversal["Schema AST traversal"] unused-field-detector["Unused-field detector"] github-action-scheduler["GitHub Action scheduler"] cleanup-agent["Cleanup agent"] validation-data-links["Validation data links"] pull-request["Pull request"] code-owner-review["Code owner review"] graphql-traffic-logs --> unused-field-detector schema-ast-traversal --> unused-field-detector unused-field-detector --> github-action-scheduler github-action-scheduler --> cleanup-agent schema-ast-traversal --> cleanup-agent cleanup-agent --> pull-request validation-data-links --> pull-request validation-data-links --> code-owner-review pull-request --> code-owner-review code-owner-review --> graphql-traffic-logs
Components
| Component | Role | Interacts with |
|---|---|---|
GraphQL traffic logs |
Record real request shapes across backend, mobile, web, and admin clients. | Unused-field detector |
Schema AST traversal |
Maps fields, resolvers, and schema structure for safe cleanup. | Unused-field detector, Cleanup agent |
Unused-field detector |
Identifies fields not requested during the chosen traffic window. | GitHub Action scheduler |
GitHub Action scheduler |
Runs daily cleanup jobs one field at a time. | Cleanup agent |
Cleanup agent |
Removes schema fields, resolvers, dead code, and tests. | Pull request |
Validation data links |
Attach traffic evidence and safety checklist to every PR. | Pull request, Code owner review |
Pull request |
Carries one cleanup change for review. | Code owner review |
Code owner review |
Human review gate for risky schema removals. | GraphQL traffic logs |
Data flow
Traffic logs prove which fields are unused, the detector selects one candidate, and the cleanup agent edits schema, resolver, dead code, and tests before opening a validated PR.
3 supporting quotes
Why this architecture
The architecture relies on real traffic because static code search misses old mobile versions and admin tooling outside primary repositories.
Models used: AI coding subagent
Scale
- The detector found over 2,600 unused fields, including nearly 200 root queries and mutations, while early agent runs removed 24 of about 200 root fields.“The data showed over 2,600 unused fields, including nearly 200 root queries and mutations.”article, stated“So far, our subagent has safely removed 24 of ~200 unused root fields. Each run costs roughly $1–3 in LLM credits.”article, stated
- Traffic analysis found more than 2,600 unused fields, including nearly 200 root queries and mutations.“The data showed over 2,600 unused fields, including nearly 200 root queries and mutations.”article, stated
- The early subagent removed 24 of about 200 unused root fields.“So far, our subagent has safely removed 24 of ~200 unused root fields. Each run costs roughly $1–3 in LLM credits.”article, stated
- Each cleanup run costs roughly $1 to $3 in LLM credits.“So far, our subagent has safely removed 24 of ~200 unused root fields. Each run costs roughly $1–3 in LLM credits.”article, stated
- A field is treated as unused only after it has not been requested in the last 30 days.“We decided to define a field as “unused” if it hadn’t been requested in the last 30 days, a reasonable window to prevent overdeletion.”article, stated
Alternatives considered (roads not taken)
One-time broad schema cleanup
Rejected because: Whatnot chose a daily background process that removes one field at a time to manage risk.
Define unused by repository references alone
Rejected because: The team used a 30-day real-traffic window to avoid deleting fields still used by deployed clients.
Deleting many unused fields in one automated change
Rejected because: The daily action removes one field at a time so schema maintenance remains a background process.
Trusting the AI cleanup proposal without reviewer evidence
Rejected because: Each PR includes validation data and a safety checklist for human reviewers.
Patterns
observability-tracing (data)
The system uses real GraphQL request logs rather than static analysis alone to decide which fields are unused.
tool-use-orchestration (orchestration)
The AI subagent follows the same code-editing steps as an engineer, removing schema fields, resolvers, dead code, and tests.
human-in-the-loop-gate (safety)
The agent opens PRs with validation data and a safety checklist, then routes them to code owners for review.
batch-offline-processing (workflow)
A scheduled GitHub Action runs the cleanup process repeatedly in the background, one field per day/run, instead of a one-time migration.
Tradeoffs
How aggressively to delete unused fields.
Chose one unused field per scheduled agent run over large batch removal of many fields at once.
Rationale: Small PRs reduce review risk and make ownership, validation, and rollback reasoning easier.
How to define unused.
Chose not requested in the last 30 days over pure repository reference absence.
Rationale: A traffic window better covers deployed mobile versions and external admin queries, while the fixed window limits overdeletion risk.
Gotchas (what bit them)
Static code search was not enough to prove a GraphQL field was unused.
Root cause: Mobile app versions and admin dashboards can execute queries outside the current primary repositories.
Resolution: Define unused based on 30 days of production GraphQL request traffic and schema field visits.
Automation proposed unsafe deletions where client-side tooling was incomplete.
Root cause: The web repository lacked the same unused GraphQL fragment linters as mobile clients.
Resolution: Improve environmental linters and code-cleanliness automation so agents can operate safely.
Evaluation
Whatnot reports field counts, removal counts, edit rates, and LLM cost from early runs.
Metrics: over 2,600 unused fields · nearly 200 unused root queries and mutations · 24 of about 200 unused root fields removed · $1-3 per run · only three PRs needed manual edits
Outcomes
- Whatnot turned GraphQL schema cleanup from an occasional neglected project into a scheduled background PR process.
- Early runs removed unused root fields with low manual-edit burden, though web-client tooling gaps remain.
Whatnot engineering article; production codebase maintenance but early-run results only.