Can AI Agents Use GraphQL Without Overloading Backend Systems?

· · Views: 1,917 · 6 min time to read

GraphQL looks like a natural API for AI agents. Give an agent access to a schema, let it translate a user’s request into a query, and it can retrieve exactly the data it needs without developers building a new endpoint for every use case. That flexibility is also where the risk begins.

A human developer usually learns not to request thousands of records, follow several expensive relationships, or repeatedly resolve the same nested fields. An AI agent has no such instinct. Its goal is to answer the user. Unless the backend enforces limits, the cost of producing that answer is someone else’s problem.

This is becoming more than an architectural thought experiment. On August 6, 2026, AWS announced support for Salt Security’s managed rule group for AWS WAF, designed to detect API attacks as well as traffic from AI agents and Model Context Protocol (MCP) endpoints. According to AWS, the ruleset targets excessive GraphQL queries. It can also identify MCP interactions, block unauthenticated MCP access, and apply rate limits to sensitive request parameters.

However, focusing solely on traffic overlooks a key issue. With GraphQL, a single valid query can significantly affect API performance without requiring a flood of requests.

Shadi Elyafi faced this challenge while building an MCP server for Fullinfo, a B2B intelligence platform with more than one million company profiles. As a senior backend engineer working with GraphQL and AWS, he needed to give AI assistants effective access to the platform while maintaining control over the API. This led to a clear guideline: an agent may need GraphQL, but rarely needs unrestricted access to write arbitrary queries.

The same thing that makes GraphQL attractive for agents also makes it risky: the client gets a lot of freedom. If you expose the entire schema and assume the model will always generate efficient queries, you are handing an important backend decision to a system that has no reason to understand what that query actually costs.

A valid GraphQL query can still be a bad query

GraphQL deliberately gives clients considerable control over the data they receive. The GraphQL specification describes this as a client-specified response: the client selects the fields it needs instead of receiving a response shape determined entirely by the server.

For AI agents, that is extremely useful. Imagine a user asks:

Find SaaS companies in Germany with 50–200 employees that raised funding in the last 24 months. Return the company name, industry, employee count, latest funding round, and up to three decision-makers in engineering or product.

An agent can translate the request into the appropriate query, choose the required fields and filters, send it to the backend, and return the result. Developers do not need to create a dedicated endpoint for that exact question. Now change the prompt:

Find SaaS companies in Germany with 50–200 employees that raised funding in the last 24 months. Find all matching companies and include their full funding history, all decision-makers and their employment history, related companies, investors and portfolio companies, plus recent hiring activity for each organization.

The second request may still produce syntactically correct and schema-valid GraphQL. It may also cause dramatically more work. Nested lists are particularly dangerous because their cost can multiply as the query traverses relationships. The current GraphQL security guidance treats depth, list depth, breadth, batching, pagination, and query complexity as separate controls; a depth limit alone addresses only part of the risk. From the model’s perspective, however, both queries may be equally successful: they answered what the user asked.

The distinction matters: the model optimizes for obtaining an answer, while the backend determines the acceptable cost of that answer.

This makes protecting GraphQL from AI agents primarily an API design problem, not a prompt-engineering problem.

Rate limiting does not limit query cost

A common defense is rate limiting. If an agent sends a high volume of requests, you can restrict it to 10, 20, or 50 requests per minute. This approach helps manage traffic and prevent obvious abuse. However, it is not enough on its own, because ten GraphQL requests may represent very different workloads.

For example, one query may retrieve only a company name and ID, while another may return hundreds of companies, their contacts, and related objects. Both are counted as a single HTTP request.

“If your protection is ‘the agent can make 20 requests per minute,’ you have limited frequency, not cost,” Elyafi says. “For GraphQL, those are two different things.”

The backend must control a query’s structure and potential cost before execution. One control is query depth. Without limits, requests can traverse relationships indefinitely, creating deeply nested operations and long resolver chains. Setting a maximum depth establishes a clear boundary.

However, depth alone is an imprecise metric. Two queries with identical nesting can have significantly different costs. For example, a field returning one object is not comparable to a field returning 1,000. A shallow operation can also repeat expensive fields through aliases, include many top-level fields, or batch several operations into one request.

This leads to a second control: query complexity or cost analysis. Each field can be assigned an estimated cost, with multipliers for lists and pagination. The server estimates the cost before execution and rejects operations that exceed the threshold.

These are standard defenses. Depth limiting and query complexity analysis are established GraphQL security practices and are part of the current GraphQL security guidance. For AI agents, these controls are even more important because the API consumer may generate new operations at runtime, rather than executing a fixed set of developer-reviewed queries.

Never let the model decide how much “all” means

Pagination is another boundary that becomes much more important once an LLM enters the loop. A human frontend developer might request 20 or 50 records because that is what the interface can display. An agent has no screen. Ask it to “find all relevant customers,” and requesting 10,000 records may appear perfectly reasonable.

The backend should therefore define the maximum page size, regardless of what the agent asks for. If first: 100 is the maximum, first: 100000 should fail validation or be capped before any resolver begins work.

Pagination also gives agents a safer way to perform larger jobs. Instead of one huge request, the system can retrieve a bounded page, process it, and explicitly decide whether another page is needed. Cursor-based pagination is a well-established pattern in production GraphQL systems; Meta, for example, has described its use in GraphQL infrastructure.

The important point is that the limit belongs to the API, not to the prompt.

You can tell an agent, “Never request more than 100 objects.” But if the API accepts 100,000, you are still relying on model behavior where a deterministic backend constraint would do the job better. A separate task-level budget should cap total pages, records, response bytes, wall-clock time, and accumulated cost across follow-up calls.

The agent probably should not see your entire GraphQL API

There is an even stronger option: do not let the AI agent generate arbitrary GraphQL at all.

In the MCP server built for Fullinfo, the model interacts with a defined set of tools covering operations such as search and collections. Nine tools are defined, while eight are exposed in the shipped configuration. The server sits between the model and the GraphQL API.

That changes the abstraction. Instead of telling an agent:

Here is our GraphQL schema. Construct whatever query you think is necessary.

You can give it a tool such as:

search_companies(country, industry, employee_range, limit)

The model maintains flexibility where it matters: interpreting user intent and selecting the right tools and parameters. However, the backend retains control over execution.

“I would rather expose a task than expose infrastructure,” Elyafi says. “The agent needs to know that it can search companies. It does not necessarily need to know every relationship and field in the GraphQL schema behind that search.”

This approach also simplifies enforcing limits. The tool can cap returned records, restrict filters, impose timeouts, control which GraphQL operation runs, and reject unsupported combinations before they reach costly resolvers.

Therefore, the safest GraphQL API for an AI agent may be one the agent never accesses directly.

Trusted operations are less exciting — and often better

MCP tools are one way to narrow the interface. For predictable workflows, companies can go further and restrict agents to predefined, reviewed GraphQL operations.

A trusted operation has a known, reviewed shape and is easier to test. A persisted hash is not an allowlist by itself: the server must reject unknown document IDs instead of accepting an arbitrary query when the hash is missing.

Variables can still change the cost of a known operation, so page sizes, ID lists, filters, and other cardinality-driving inputs still need hard limits. This sacrifices flexibility, but not every AI feature needs arbitrary query generation. If most agent requests map to a small set of business operations, a reviewed operation set is often a better interface than the entire graph.

Watch cost, not just traffic

Even with these controls, teams need observability.

Traditional API dashboards focus on request rates, HTTP errors, and latency. While these metrics remain important, agent-generated GraphQL introduces another key dimension: the workload each operation generates. Teams should monitor operation or tool name, estimated complexity, page size, response bytes, execution time, resolver behavior, database calls and rows, cache behavior, retries, and rejection reason. The objective is to compare estimated and actual cost and identify requests that succeed technically but incur excessive resource costs. Metrics should be attributable to a user and tenant so one agent cannot consume a shared budget unnoticed.

Products like the new Salt ruleset for AWS WAF complement a broader security architecture. Detecting excessive GraphQL activity and identifying MCP traffic adds visibility and protection. However, these tools should not replace internal GraphQL constraints. A WAF can detect suspicious behavior at the perimeter but cannot account for all business-specific costs within resolvers.

GraphQL security best practices combine multiple controls; no single measure is sufficient. Trusted documents, pagination, depth and breadth limits, batch limits, rate limits, complexity analysis, input validation, authentication, and authorization address distinct risks. The current GraphQL security guidance presents these layers together.

Treat the agent as an untrusted API client

Many teams assume that an AI agent can be fully trusted because it is part of an application. It should instead be treated as a fast, creative, and sometimes unpredictable API client.

An AI agent may misunderstand instructions, generate inefficient queries, or retry if a request is delayed. Users may also assign broad tasks. As agents plan multi-step operations, a single user request can result in multiple API interactions.

These scenarios do not require the model to be malicious. The backend should enforce the same authentication, authorization, validation, and resource limits it uses for any other untrusted client and, in some cases, stricter controls.

Set maximum query depth and list depth, limit breadth, aliases, and batch size, calculate complexity, and cap pagination. Restrict expensive operations to specific tools. Use trusted operations when dynamic queries offer little value. Rate-limit requests, but distinguish request frequency from computational cost. Set task-level budgets for total pages, records, time, and accumulated cost, and monitor agent activity in production.

GraphQL can be an excellent backend for AI agents. Its flexibility lets you connect natural-language requests to rich enterprise data without creating an endpoint for every question.

However, that flexibility should end at the model boundary. The agent can determine user intent, but the backend must control the allowable cost of fulfilling that request.

Share
f 𝕏 in
Copied