# Rate Limits and Budgets

For Agent-to-Agent (A2A) traffic, caller-level limits are configured on the caller API key. A2A calls share the key's request and concurrency limits with model traffic. In AISIX Enterprise and AISIX Cloud, budgets that cover the key also apply, but A2A calls report zero cost and do not increase tracked spend.

There is no separate A2A traffic-control resource. Configure rate limits on the caller API key and, in AISIX Enterprise and AISIX Cloud, budgets at a scope that covers the key. Then verify the behavior on `/a2a/<agent>`.

## Prerequisites[​](#prerequisites "Direct link to Prerequisites")

Complete [Set Up Agent Gateway](https://docs.api7.ai/ai-gateway/agent-gateway/setup.md). Use its control-plane path for AISIX Enterprise or AISIX Cloud and its resources-file path for AISIX OSS. Keep the shell, gateway, and test agent running to verify the limit.

## Where Controls Apply[​](#where-controls-apply "Direct link to Where Controls Apply")

The gateway applies traffic controls to each JSON-RPC call at `/a2a/<agent>`. Agent-card discovery is not rate-limited. A throttled caller can still fetch the card of an agent its key may access, but it cannot invoke the agent again until the window resets.

When a rate limit or budget rejects a call, AISIX returns before contacting the upstream agent and records the rejected call as a [usage event](https://docs.api7.ai/ai-gateway/agent-gateway/observability.md).

Because an A2A call resolves no model, model-scoped rate-limit policies do not apply. Request-level controls on the caller API key do apply.

## Applicable Rate Limits[​](#applicable-rate-limits "Direct link to Applicable Rate Limits")

A caller API key's `rate_limit` object supports request-rate, token-rate, and concurrency limits. Only request-rate and concurrency limits directly meter A2A calls:

| Limit                      | Applies to A2A calls | Behavior                                                                                                                                                                          |
| -------------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `rps`, `rpm`, `rph`, `rpd` | Yes                  | Each `/a2a/<agent>` call counts as one request in the matching window.                                                                                                            |
| `concurrency`              | Yes                  | Each in-flight call holds one permit until it returns.                                                                                                                            |
| `tpm`, `tpd`               | No                   | Estimated A2A token counts are reported but are not added to token windows. An A2A call can still be rejected if the key's model traffic already exhausted a shared token window. |

Use a request-rate limit or `concurrency` to control A2A call volume. A token limit alone does not cap A2A calls.

For the complete field reference and counter-storage options, see [API Key and Model Rate Limits](https://docs.api7.ai/ai-gateway/traffic-controls/rate-limits.md).

## Set a Caller Rate Limit[​](#set-a-caller-rate-limit "Direct link to Set a Caller Rate Limit")

The following examples limit the setup guide's caller API key to one request per minute.

### AISIX Enterprise or AISIX Cloud[​](#aisix-enterprise-or-aisix-cloud "Direct link to AISIX Enterprise or AISIX Cloud")

Update the existing caller API key:

```
curl -fsS -X PATCH \

  "$AISIX_CP/environments/$ENV_ID/api_keys/$API_KEY_ID" \

  -H "Authorization: Bearer $AISIX_TOKEN" \

  -H "Content-Type: application/json" \

  -d '{

    "rate_limit": {

      "rpm": 1

    }

  }' | jq
```

The partial update retains the key's model, MCP, and agent grants. The control plane projects the change to attached gateways automatically. Send `"rate_limit": null` to clear the inline limit.

### AISIX OSS[​](#aisix-oss "Direct link to AISIX OSS")

Add `rate_limit` to the caller entry in `resources.yaml`:

resources.yaml (caller rate limit)

```
api_keys:

  - display_name: quickstart-caller

    key_env: CALLER_API_KEY

    allowed_models:

      - gpt-4o-mini

    allowed_agents:

      - echo-agent

    rate_limit:

      rpm: 1
```

Validate the complete file and reload it:

```
docker exec aisix-quickstart \

  aisix validate --resources /etc/aisix/resources.yaml



docker kill --signal HUP aisix-quickstart
```

Remove `rate_limit` to clear the inline limit.

## Verify the Rate Limit[​](#verify-the-rate-limit "Direct link to Verify the Rate Limit")

After the configuration is active, call the agent twice within one minute:

```
for call in 1 2; do

  curl -sS -o "/tmp/a2a-rate-limit-${call}.json" \

    -w "call ${call}: HTTP %{http_code}\n" \

    -X POST "$AISIX_PROXY/a2a/echo-agent" \

    -H "Authorization: Bearer $AISIX_A2A_KEY" \

    -H "Content-Type: application/json" \

    -d '{

      "jsonrpc": "2.0",

      "id": "req-rate-limit",

      "method": "SendMessage",

      "params": {

        "message": {

          "messageId": "msg-rate-limit",

          "role": "ROLE_USER",

          "parts": [{"text": "Test the caller rate limit"}]

        }

      }

    }'

done
```

The command prints HTTP `200` for the first call and HTTP `429` for the second. The rejected call does not reach the upstream agent.

## Apply Control-Plane Budgets[​](#apply-control-plane-budgets "Direct link to Apply Control-Plane Budgets")

Budgets are configured through the control plane and enforced by its attached gateways. When a budget that covers the caller API key is exhausted, AISIX rejects that key's A2A calls with a `budget_exceeded` error before contacting the upstream agent.

The A2A protocol has no provider-usage block, so AISIX estimates text tokens for telemetry and records `cost_usd` as zero. A2A calls therefore do not add spend to a budget. A budget exhausted by the caller's model traffic still blocks that caller's A2A calls because both use the same caller API key.

AISIX OSS has no budget-management service. Use caller API key request and concurrency limits to control A2A call volume. See [Budgets](https://docs.api7.ai/ai-gateway/traffic-controls/budgets.md) for control-plane budget targets, rejection behavior, and caching.

## Next Steps[​](#next-steps "Direct link to Next Steps")

You have now applied caller API key controls to A2A traffic. Use these guides to observe or refine the result:

* [Observability](https://docs.api7.ai/ai-gateway/agent-gateway/observability.md): review the usage events and metrics emitted by A2A calls.
* [Control Agent Access](https://docs.api7.ai/ai-gateway/agent-gateway/agent-access-control.md): scope caller API keys to specific agents or patterns.
* [API Key and Model Rate Limits](https://docs.api7.ai/ai-gateway/traffic-controls/rate-limits.md): review all rate-limit fields.
* [Budgets](https://docs.api7.ai/ai-gateway/traffic-controls/budgets.md): configure control-plane budget targets and rejection behavior.
