
Apply different rate limiting policies to separate apps/APIs
As a DevOps or infrastructure engineer, you want to protect all your services from abuse and enforce fairness, but sometimes you can't apply the same rate limiting capacity and sliding window to all service equally.
To apply different rate limiting policies to individual services, you'll use a combination of Cloud Endpoints, internal Agent Endpoints, and Traffic Policy rules. You'll use the Cloud Endpoint to route traffic to specific services, then compose the rate-limit
Traffic Policy action onto the request lifecycle at the agent level.
How to use this recipe
1. Define your internal agent endpoints and rate limiting rules
Assuming that your API services run on the same system or are accessible on the same network, you can use a single ngrok agent and the configuration file to create multiple agent endpoints.
version: 3
agent:
authtoken: $YOUR_NGROK_AUTHTOKEN
endpoints:
- url: https://foo.internal
upstream:
url: 8080
traffic_policy:
on_http_request:
- actions:
- type: rate-limit
config:
name: Allow 100 requests per minute
algorithm: sliding_window
capacity: 100
rate: 60s
bucket_key:
- conn.client_ip
- name: bar
url: https://bar.internal
upstream:
url: 8081
traffic_policy:
on_http_request:
- actions:
- type: rate-limit
config:
name: Allow 500 requests per minute
algorithm: sliding_window
capacity: 500
rate: 60s
bucket_key:
- conn.client_ip
Tip: If your services run on different machines, you can also use the ngrok agent with a Traffic Policy file and the --traffic-policy-file
argument.
2. Start your internal agent endpoints
On the server where ngrok and your services run, start ngrok and your endpoints.
ngrok start foo bar
3. Reserve a domain
Navigate to the Domains section of the ngrok dashboard and click New + to reserve a domain like https://your-api.ngrok.app
, which we’ll refer to $YOUR_NGROK_DOMAIN
from here on out.
4. Create a cloud endpoint
Navigate to the Endpoints section of the ngrok dashboard, then click New + and Cloud Endpoint to create a new cloud endpoint on $YOUR_NGROK_DOMAIN
.
5. Apply Traffic Policy to your cloud endpoint for path-based routing
With CEL interpolation, which takes the request's path and removes the leading forward slash, you can route requests from https://$YOUR_NGROK_DOMAIN/foo
to https://foo.internal
and so on.
on_http_request:
- actions:
- type: forward-internal
config:
url: https://${req.url.path.split("/")[1]}.internal
What you get from this recipe
You now have multiple services publicly accessible on a single hostname and path-based routing, but with different rate limiting limits based on the nature of the service, how expensive it is to run, or how often you expect clients to use them.
Plus, by composing the rate limiting rules on the agent endpoints instead of the cloud endpoint, you've created a separation of concerns between your "front door" infrastructure and the lifecycle of your individual upstream services. That "shape" makes your Traffic Policy configures more modular, instead of relying on a single verbose configuration to do all traffic management work.
What's next?
- Apply some form of authentication to your services from your cloud endpoint, like OAuth or JWT validation.
- Use a single ngrok agent with multiple upstream services using the agent configuration file.
- Opt for subdomain- or header-based routing instead of path.