Flow Example
In this configuration:
- API requests to
api.com/*
are managed based on both monthly and daily quotas. - Requests are filtered by the
x-lunar-consumer-tag
header to differentiate between production and staging traffic, with each environment having distinct quotas. - Production traffic is prioritized over staging traffic, with production requests receiving higher priority (1) and staging traffic receiving lower priority (2).
- Requests that exceed the limits or queuing capacity will receive a 429 Too Many Requests response.
Flow Configuration
/etc/lunar-proxy/flows/flow.yaml
name: MonthlyAndDailyLimit-Prod
filter:
url: api.com/*
headers:
- key: x-lunar-consumer-tag
value: production
- key: x-lunar-consumer-tag
value: staging
processors:
QueueLimiter:
processor: Queue
parameters:
- key: quota_id
value: LimiterSecond
- key: ttl_seconds
value: 12
- key: queue_size
value: 10
- key: priority_group_by_header
value: x-lunar-consumer-tag
- key: priority_groups
value:
production: 1
staging: 2
LimiterProd:
processor: Limiter
parameters:
- key: quota_id
value: LimiterProd
LimiterStaging:
processor: Limiter
parameters:
- key: quota_id
value: LimiterStaging
ProdFilter:
processor: Filter
parameters:
- key: header
value: x-lunar-consumer-tag=production
GenerateResponseTooManyRequests:
processor: GenerateResponse
parameters:
- key: status
value: 429
- key: body
value: "Quota Exceeded. Please try again later."
- key: Content-Type
value: text/plain
flow:
request:
- from:
stream:
name: globalStream
at: start
to:
processor:
name: QueueLimiter
- from:
processor:
name: QueueLimiter
condition: blocked
to:
processor:
name: GenerateResponseTooManyRequests
- from:
processor:
name: QueueLimiter
condition: allowed
to:
processor:
name: ProdFilter
- from:
processor:
name: ProdFilter
condition: hit
to:
processor:
name: LimiterProd
- from:
processor:
name: LimiterProd
condition: above_limit
to:
processor:
name: GenerateResponseTooManyRequests
- from:
processor:
name: LimiterProd
condition: below_limit
to:
stream:
name: globalStream
at: end
- from:
processor:
name: ProdFilter
condition: miss
to:
processor:
name: LimiterStaging
- from:
processor:
name: LimiterStaging
condition: above_limit
to:
processor:
name: GenerateResponseTooManyRequests
- from:
processor:
name: LimiterStaging
condition: below_limit
to:
stream:
name: globalStream
at: end
response:
- from:
processor:
name: GenerateResponseTooManyRequests
to:
stream:
name: globalStream
at: end
Flow Parameters
Parameter | Example Value | Description |
---|---|---|
name | MonthlyAndDailyLimit-Prod | The name of the flow, used to identify it in configurations. |
filter.url | api.com/* | Filters API requests based on the URL pattern for which the flow applies. |
filter.header.key | x-lunar-consumer-tag | The header key used to differentiate between traffic types (e.g., production, staging). |
filter.header.values | ['production', 'staging'] | The values that the header must match to apply specific limits (i.e., production and staging). |
processors.QueueLimiter.processor | Queue | Defines the processor responsible for managing the request queue and handling priorities. |
processors.QueueLimiter.parameters.key | quota_id , ttl_seconds , queue_size , priority_group_by_header , priority_groups | Parameters for configuring the queue's quota, time-to-live (TTL), size, and priority logic. |
processors.LimiterProd.processor | Limiter | Applies rate limiting to production traffic, using the defined quota for production. |
processors.LimiterStaging.processor | Limiter | Applies rate limiting to staging traffic, using the defined quota for staging. |
processors.ProdFilter.processor | Filter | Filters production traffic based on the x-lunar-consumer-tag header (set to production ). |
processors.GenerateResponseTooManyRequests.processor | GenerateResponse | Generates a response when the request exceeds the rate limit or the queue limit, returning an HTTP 429 response. |
flow.request.from.stream.name | globalStream | The input stream where the request flow starts. |
flow.request.to.processor.name | QueueLimiter , ProdFilter , LimiterProd , GenerateResponseTooManyRequests , etc. | The processors to which the request flow is routed, depending on whether it is blocked or allowed. |
flow.response.from.processor.name | GenerateResponseTooManyRequests | Generates the response for requests that exceed limits (429 response). |
flow.response.to.stream.name | globalStream | The output stream to which the response is sent. |
/etc/lunar-proxy/quotas/quota.yaml
quota:
id: LimiterMonth
filter:
url: api.com/*
strategy:
fixed_window:
max: 10000000
interval: 1
interval_unit: month
monthly_renewal:
day: 1
hour: 11
minute: 0
second: 0
timezone: UTC
internal_limits:
- id: LimiterSecond
parent_id: LimiterMonth
strategy:
fixed_window:
max: 1
interval: 1
interval_unit: second
- id: LimiterProd
parent_id: LimiterMonth
filter:
headers:
- key: x-lunar-consumer-tag
value: production
strategy:
fixed_window:
max: 100000
interval: 1
interval_unit: day
- id: LimiterStaging
parent_id: LimiterMonth
filter:
headers:
- key: x-lunar-consumer-tag
value: staging
strategy:
fixed_window:
max: 20000
interval: 1
interval_unit: day
spillover:
max: 100
Quota Parameters
Parameter | Example Value | Description |
---|---|---|
quota.id | LimiterMonth | The unique identifier for the monthly quota applied to the flow. |
filter.url | api.com/* | Filters API requests based on the URL pattern for which the quota applies. |
strategy.fixed_window.max | 10000000 | The maximum number of requests allowed within the specified interval (monthly quota). |
strategy.fixed_window.interval | 1 | The interval duration for which the requests are counted. |
strategy.fixed_window.interval_unit | month | The unit of time for the interval, in this case, a month. |
internal_limits.id | LimiterSecond , LimiterProd , LimiterStaging | The unique identifiers for internal limits nested within the parent quota. |
internal_limits.parent_id | LimiterMonth | Links the child quotas to the parent monthly quota. |
internal_limits.strategy.fixed_window.max | 100000 , 1 , 100000 , 20000 | The maximum number of requests allowed within each child quota (daily, per second, production, staging). |
internal_limits.filter.header.key | x-lunar-consumer-tag | The header used to differentiate between production and staging traffic. |
internal_limits.strategy.spillover.max | 100 | The spillover limit for handling requests beyond the quota (applies to the staging environment). |