Rate limit API requests
Protect your portal APIs with rate limiting to control usage, prevent abuse, and enforce fair access across subscriptions.
Rate limiting controls how many requests a client can make to an API within a given time window. In a developer portal, rate limiting is important for several reasons:
- Prevent abuse: Stop a single user or application from overwhelming your APIs with excessive requests.
- Enforce fair usage: Ensure all portal users get consistent, predictable access to shared API resources.
- Support tiered access: Apply different limits to different subscriptions, so premium or higher-tier users can access APIs at a higher rate than others.
- Protect backends: Shield upstream services from traffic spikes that could degrade performance or cause outages.
Solo Enterprise for kgateway supports two levels of rate limiting for portal APIs.
- Default rate limit: You can set a default rate limit that applies to all subscriptions to an API.
- Subscription-specific rate limits: Portal admins can override the default rate limit with a custom rate limit for a specific subscription by using the portal frontend.
Before you begin
Portal admins must complete the following tasks:
- Set up a portal web server.
- Secure the login to the portal frontend.
- Optional: Set up a backing database for your portal. This database is used to store the rate limit configurations that you create in the Portal frontend app.
- Set up API credential management to protect your API product and allow specific rate limit settings for a subscriptions.
Portal users must complete the following tasks:
- Create a Team, an app, and a subscription to your app.
- Create API credentials so that you can later test the rate limit settings for the API.
Before you begin
Complete the guide to set up credential management for APIs by using API keys or an OAuth client.
Step 1: Set up a default rate limit for an API
You can enforce basic rate limits for an API that automatically applies to all subscriptions to that API. The following example walks you through how to set up a default rate limit for the httpbin API.
Create a RateLimitConfig to limit requests to 2 per minute.
kubectl apply -f- <<EOF apiVersion: ratelimit.solo.io/v1alpha1 kind: RateLimitConfig metadata: name: httpbin-rl namespace: default spec: raw: setDescriptors: - simpleDescriptors: - key: generic_key value: counter rateLimit: requestsPerUnit: 2 unit: MINUTE rateLimits: - setActions: - genericKey: descriptorValue: counter EOFCreate an EnterpriseKgatewayTrafficPolicy that references the RateLimitConfig that you created. Apply the policy to the httpbin HTTPRoute.
kubectl apply -f- <<EOF apiVersion: enterprisekgateway.solo.io/v1alpha1 kind: EnterpriseKgatewayTrafficPolicy metadata: name: ratelimit namespace: default spec: targetRefs: - group: gateway.networking.k8s.io kind: HTTPRoute name: httpbin-route entRateLimit: global: rateLimitConfigRefs: - name: httpbin-rl EOFVerify that the rate limit is applied. For example, Portal users can follow the steps in View and test API access to send multiple requests to the httpbin API via the frontend app. If you have a valid API key or access token, you can also use the following curl requests. Verify that you are rate limited after 2 successful requests, and that a 429 HTTP response code is returned.
Cloud Provider Load Balancer:
for i in {1..3}; do curl -vik ${INGRESS_GW_ADDRESS}:8080/httpbin/headers \ -H "host: api.example.com" \ -H "api-key: $API_KEY"; donePort-forward for local testing:
for i in {1..3}; do curl -vik localhost:8080/httpbin/headers \ -H "host: api.example.com" \ -H "api-key: $API_KEY"; doneCloud Provider Load Balancer:
for i in {1..3}; do curl -vik ${INGRESS_GW_ADDRESS}:8080/httpbin/headers \ -H "host: api.example.com" \ -H "Authorization: Bearer $ACCESS_TOKEN"; donePort-forward for local testing:
for i in {1..3}; do curl -vik localhost:8080/httpbin/headers \ -H "host: api.example.com" \ -H "Authorization: Bearer $ACCESS_TOKEN"; doneExample output:
HTTP/2 200 x-powered-by: tinyhttp access-control-allow-origin: * access-control-allow-methods: GET, HEAD, PUT, PATCH, POST, ... HTTP/2 200 x-powered-by: tinyhttp access-control-allow-origin: * access-control-allow-methods: GET, HEAD, PUT, PATCH, POST, ... HTTP/2 429 x-envoy-ratelimited: true server: envoy
Step 2: Allow overwriting default rate limits via the frontend app
You might want to customize the rate limiting settings for a particular team or app and not use the default rate limiting settings that you applied earlier. To do that, you can use the dynamicMetadata feature in a RateLimitConfig to overwrite any default rate limits with the limits that were configured via the Portal frontend app for a particular API subscription. If no custom rate limit exists for an API subscription, the default rate limits are still enforced.
Update the RateLimitConfig that you created earlier to add the
dynamicMetadatafeature. In this example, you instruct the portal web server to overwrite the default rate limit settings with the settings for a particular API subscription. ThemetadataKeypath has two entries: the name of theportalAuthsection in the AuthConfig that you used when you set up credential management for the API, andrateLimit, which is the key that ExtAuth sets in the dynamic metadata when it processes the subscription. This way, Portal automatically handles all the dynamic metadata that is required to enforce rate limiting for a particular API subscription.kubectl apply -f- <<EOF apiVersion: ratelimit.solo.io/v1alpha1 kind: RateLimitConfig metadata: name: httpbin-rl namespace: default spec: raw: setDescriptors: - simpleDescriptors: - key: generic_key value: counter rateLimit: requestsPerUnit: 2 unit: MINUTE rateLimits: - setActions: - genericKey: descriptorValue: counter limit: dynamicMetadata: metadataKey: key: "envoy.filters.http.ext_authz" path: - key: "httpbinAuth" - key: "rateLimit" EOFIn your browser, open the portal frontend app, such as
http://portal.example.com:8080/and log in as a Portal admin.In the frontend app, go to Subscriptions and find the subscription for which you want to rate limit requests.
Click Edit Rate Limit.
Select the number of requests that you want to allow in the Requests Per Unit field and the Unit. For example, you might want to allow a maximum of 5 requests per minute.


Click Save to save your settings.
Verify that the rate limit is applied. For example, Portal users can follow the steps in View and test API access to send multiple requests to the httpbin API via the frontend app. If you have a valid API key or access token, you can also use the following curl requests. Verify that you are rate limited after 5 successful requests instead of 2, and that a 429 HTTP response code is returned.
Cloud Provider Load Balancer:
for i in {1..6}; do curl -I ${INGRESS_GW_ADDRESS}:8080/httpbin/headers \ -H "host: api.example.com" \ -H "api-key: $API_KEY"; donePort-forward for local testing:
for i in {1..6}; do curl -I localhost:8080/httpbin/headers \ -H "host: api.example.com" \ -H "api-key: $API_KEY"; doneCloud Provider Load Balancer:
for i in {1..6}; do curl -I ${INGRESS_GW_ADDRESS}:8080/httpbin/headers \ -H "host: api.example.com" \ -H "Authorization: Bearer $ACCESS_TOKEN"; donePort-forward for local testing:
for i in {1..6}; do curl -I localhost:8080/httpbin/headers \ -H "host: api.example.com" \ -H "Authorization: Bearer $ACCESS_TOKEN"; doneExample output:
HTTP/1.1 200 OK access-control-allow-credentials: true access-control-allow-origin: * ... HTTP/1.1 200 OK access-control-allow-credentials: true access-control-allow-origin: * ... HTTP/1.1 200 OK access-control-allow-credentials: true access-control-allow-origin: * ... HTTP/1.1 200 OK access-control-allow-credentials: true access-control-allow-origin: * ... HTTP/1.1 200 OK access-control-allow-credentials: true access-control-allow-origin: * ... HTTP/1.1 429 Too Many Requests retry-after: 60 x-envoy-ratelimited: true ...