0
0
GraphqlHow-ToBeginner · 3 min read

How to Rate Limit GraphQL API: Simple Guide and Example

To rate limit a GraphQL API, use middleware that tracks request counts per user or IP and blocks requests exceeding a set limit. Common tools include express-rate-limit for Node.js servers, applied before the GraphQL handler to control query frequency and prevent abuse.
📐

Syntax

Rate limiting in GraphQL is usually done by adding middleware before the GraphQL server processes requests. The middleware checks how many requests a client has made in a time window and blocks excess requests.

Key parts:

  • windowMs: Time frame for counting requests (e.g., 15 minutes).
  • max: Maximum allowed requests in that time.
  • keyGenerator: Function to identify clients (by IP or user ID).
  • handler: Function called when limit is exceeded.
javascript
const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // limit each IP to 100 requests per windowMs
  keyGenerator: (req) => req.ip, // identify client by IP
  handler: (req, res) => {
    res.status(429).json({ error: 'Too many requests, please try again later.' });
  }
});

app.use('/graphql', limiter, graphqlHTTP({ schema }));
💻

Example

This example shows how to add rate limiting to a GraphQL API using express-rate-limit with an Express server. It limits each IP to 5 requests per minute and returns an error if exceeded.

javascript
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { buildSchema } = require('graphql');
const rateLimit = require('express-rate-limit');

// Define a simple schema
const schema = buildSchema(`
  type Query {
    hello: String
  }
`);

// Root resolver
const root = {
  hello: () => 'Hello world!'
};

const app = express();

// Rate limiter middleware
const limiter = rateLimit({
  windowMs: 60 * 1000, // 1 minute
  max: 5, // limit each IP to 5 requests per windowMs
  handler: (req, res) => {
    res.status(429).json({ error: 'Too many requests, slow down!' });
  }
});

// Apply rate limiter to /graphql endpoint
app.use('/graphql', limiter, graphqlHTTP({
  schema: schema,
  rootValue: root,
  graphiql: true
}));

app.listen(4000, () => {
  console.log('Running a GraphQL API server at http://localhost:4000/graphql');
});
Output
Running a GraphQL API server at http://localhost:4000/graphql
⚠️

Common Pitfalls

  • Not applying rate limiting middleware before the GraphQL handler: This causes unlimited requests to reach your API.
  • Using IP only for key generation in shared networks: This can block many users behind the same IP.
  • Setting limits too low or too high: Too low frustrates users; too high fails to protect the server.
  • Ignoring authentication: For authenticated APIs, use user ID instead of IP to track limits.
javascript
/* Wrong: Applying limiter after GraphQL handler (ineffective) */
app.use('/graphql', graphqlHTTP({ schema }), limiter);

/* Right: Apply limiter before GraphQL handler */
app.use('/graphql', limiter, graphqlHTTP({ schema }));
📊

Quick Reference

Tips for effective GraphQL rate limiting:

  • Use middleware like express-rate-limit before your GraphQL server.
  • Identify clients by IP or user ID depending on your app.
  • Set reasonable max and windowMs values based on expected traffic.
  • Return clear error messages with HTTP 429 status when limits are exceeded.
  • Consider more advanced solutions like Redis stores for distributed rate limiting.

Key Takeaways

Apply rate limiting middleware before the GraphQL handler to control request flow.
Use client identifiers like IP or user ID to track request counts accurately.
Set limits that balance user experience and server protection.
Return HTTP 429 status with a clear message when limits are exceeded.
Consider distributed stores like Redis for scalable rate limiting.