Rate limit A2A traffic

Incompatible with
on-prem
Minimum Version
AI Gateway - 2.0
Previous Versions of this page
TL;DR

Create a Rate Limiting Advanced Policy and attach it to an AI Agent. Requests that exceed the limit are rejected with 429. By default rate limits apply per IP address. However, you can combine this with an authentication policy so that rate limits apply per consumer.

Prerequisites

This is a Konnect tutorial and requires a Konnect personal access token.

  1. Create a new personal access token by opening the Konnect PAT page and selecting Generate Token.

  2. Export your token to an environment variable:

    export KONNECT_TOKEN='YOUR_KONNECT_PAT'
  3. Run the AI Gateway quickstart script to automatically provision a control plane and data plane in Kong Konnect, and configure your environment:

    curl -Ls https://get.konghq.com/ai | bash -s -- -k $KONNECT_TOKEN 

This sets up a AI Gateway control plane named ai-quickstart, provisions a local data plane, and prints out the following environment variables export:

export AI_GATEWAY_ID=your-gateway-id
export KONNECT_TOKEN=$KONNECT_TOKEN
export KONNECT_CONTROL_PLANE_NAME=ai-quickstart
export KONNECT_CONTROL_PLANE_URL=https://us.api.konghq.com
export KONNECT_PROXY_URL='http://localhost:8000'

Copy and paste these into your terminal to configure your session.

This tutorial uses kongctl to manage Konnect resources programmatically. We recommend keeping kongctl up to date with the latest version (1.13.0).

  1. Install kongctl from developer.konghq.com/kongctl.
  2. Verify the installation:

    kongctl version
  1. Create an OpenAI account.
  2. Get an API key.
  3. Export your key:
    export OPENAI_API_KEY='YOUR_OPENAI_API_KEY'

You need a running A2A-compliant agent. This guide uses a sample KongAir travel agent that uses OpenAI and LangGraph to answer flight route queries.

Create a docker-compose.yaml file:

cat <<'EOF' > docker-compose.yaml
services:
  a2a-agent:
    container_name: a2a-kongair-agent
    image: ghcr.io/tomek-labuk/a2a-kongair-openai-agent:1.0.0
    environment:
      - OPENAI_API_KEY=${OPENAI_API_KEY}
      - OPENAI_MODEL=gpt-5-mini
      - KONGAIR_BASE_URL=https://api.kong-air.com
      - PUBLIC_AGENT_URL=http://localhost:10000
    ports:
      - "10000:10000"
EOF

Start the agent:

docker compose up -d --wait

The agent listens on port 10000 and uses the A2A JSON-RPC protocol to handle flight route queries. In this guide, the gateway service points to host.docker.internal:10000 instead of the container name because Kong Gateway runs in its own container with a separate DNS resolver.

Create an AI Agent and attach a rate limiting AI Policy

Create an AI Agent entity that proxies A2A traffic to your upstream agent and a Rate Limiting Advanced Policy that counts requests per IP and rejects requests that exceed the configured limit.

This configuration allows 5 requests per 30 seconds. These settings are intentionally low to make it easy to trigger during testing. The AI Policy is attached to the AI Agent by using !ref rate-limit-bookings-agent#name to refer to it by name.

kongctl apply -f - --auto-approve --pat "$KONNECT_TOKEN" << 'EOF'
ai_gateway_policies:
  - ref: rate-limit-bookings-agent
    ai_gateway: !lookup {id: !env AI_GATEWAY_ID}
    name: rate-limit-bookings-agent
    display_name: "Rate limit Kong Air Flight Booking Agent"
    type: rate-limiting-advanced
    config:
      limit:
        - 5
      window_size:
        - 30
      sync_rate: -1
      namespace: a2a-kongair-agent
      strategy: local
ai_gateway_agents:
  - ref: kongair-flight-booking-agent
    ai_gateway: !lookup {id: !env AI_GATEWAY_ID}
    display_name: "Kong Air Flight Booking Agent"
    type: a2a
    enabled: true
    policies:
      - !ref rate-limit-bookings-agent#name
    config:
      url: http://host.docker.internal:10000
      route:
        paths:
          - /a2a
        methods:
          - GET
          - POST
        protocols:
          - http
          - https
        strip_path: true
      logging:
        payloads: true
        statistics: true
        max_payload_size: 1048576
      max_request_body_size: 8388608
EOF

The limit and window_size are intentionally set low for testing. You should adjust these to appropriate values for production workloads.

Validate rate limit headers

Send an authenticated request to the agent card endpoint and inspect the response headers. The agent card is a lightweight A2A operation (GetAgentCard) that returns agent metadata without calling an LLM, so responses are instant.

curl -i -X GET "$KONNECT_PROXY_URL/a2a/.well-known/agent-card.json" \
     --no-progress-meter --fail-with-body  \
     -H "apikey: a2a-secret-key-1"

The response includes rate limit headers:

HTTP/2 200
...
ratelimit-limit: 5
ratelimit-remaining: 4
ratelimit-reset: 30
x-ratelimit-limit-30: 5
x-ratelimit-remaining-30: 4

ratelimit-remaining decreases with each request. ratelimit-reset shows the seconds until the window resets.

Validate rate limit enforcement

Send 6 requests to the agent card endpoint in a loop to exceed the limit. The AI Agent detects each request as an A2A GetAgentCard operation, so the rate limit applies the same way it does for message/send or any other A2A method.

for _ in {1..5}; do
  curl  -i $KONNECT_PROXY_URL/a2a/.well-known/agent-card.json \
       -H "apikey: a2a-secret-key-1" 
  echo
done

On the last request, you should get a 429 response with the message API rate limit exceeded.

The first four requests return HTTP status: 200. The 5th request returns HTTP status: 429.

Cleanup

docker compose down
docker rm -f a2a-kongair-agent

To clean up all AI Gateway resources created in this guide, run:

curl -Ls https://get.konghq.com/ai | bash -s -- -d

FAQs

Yes. Without an authentication policy, the Rate Limiting Advanced policy falls back to rate limiting by IP address. Add an authentication policy if you need per-consumer limits.

Rate limiting applies at request time, before the upstream responds. A streaming SSE response that is already in progress is not interrupted. The rate limit check happens when the client sends the next request.

AI Rate Limiting Advanced limits based on LLM token consumption (prompt and completion tokens). The AI Agent doesn’t extract token counts from A2A responses, so an AI Rate Limiting Advanced Policy has no token data to act on. Use the standard Rate Limiting Advanced Policy for A2A traffic.

Help us make these docs great!

Kong Developer docs are open source. If you find these useful and want to make them better, contribute today!