Skip to main content
Version: Next

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

ParameterExample ValueDescription
nameMonthlyAndDailyLimit-ProdThe name of the flow, used to identify it in configurations.
filter.urlapi.com/*Filters API requests based on the URL pattern for which the flow applies.
filter.header.keyx-lunar-consumer-tagThe 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.processorQueueDefines the processor responsible for managing the request queue and handling priorities.
processors.QueueLimiter.parameters.keyquota_id, ttl_seconds, queue_size, priority_group_by_header, priority_groupsParameters for configuring the queue's quota, time-to-live (TTL), size, and priority logic.
processors.LimiterProd.processorLimiterApplies rate limiting to production traffic, using the defined quota for production.
processors.LimiterStaging.processorLimiterApplies rate limiting to staging traffic, using the defined quota for staging.
processors.ProdFilter.processorFilterFilters production traffic based on the x-lunar-consumer-tag header (set to production).
processors.GenerateResponseTooManyRequests.processorGenerateResponseGenerates a response when the request exceeds the rate limit or the queue limit, returning an HTTP 429 response.
flow.request.from.stream.nameglobalStreamThe input stream where the request flow starts.
flow.request.to.processor.nameQueueLimiter, 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.nameGenerateResponseTooManyRequestsGenerates the response for requests that exceed limits (429 response).
flow.response.to.stream.nameglobalStreamThe 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

ParameterExample ValueDescription
quota.idLimiterMonthThe unique identifier for the monthly quota applied to the flow.
filter.urlapi.com/*Filters API requests based on the URL pattern for which the quota applies.
strategy.fixed_window.max10000000The maximum number of requests allowed within the specified interval (monthly quota).
strategy.fixed_window.interval1The interval duration for which the requests are counted.
strategy.fixed_window.interval_unitmonthThe unit of time for the interval, in this case, a month.
internal_limits.idLimiterSecond, LimiterProd, LimiterStagingThe unique identifiers for internal limits nested within the parent quota.
internal_limits.parent_idLimiterMonthLinks the child quotas to the parent monthly quota.
internal_limits.strategy.fixed_window.max100000, 1, 100000, 20000The maximum number of requests allowed within each child quota (daily, per second, production, staging).
internal_limits.filter.header.keyx-lunar-consumer-tagThe header used to differentiate between production and staging traffic.
internal_limits.strategy.spillover.max100The spillover limit for handling requests beyond the quota (applies to the staging environment).