# How to Configure Rate Limiting with Multiple Strategies in Easegress

> Learn to configure rate limiting with multiple strategies in Easegress. Define distinct policies, set fallbacks, and bind them to URL rules for flexible endpoint throttling.

- Repository: [MegaEase/easegress](https://github.com/megaease/easegress)
- Tags: how-to-guide
- Published: 2026-03-07

---

**To configure rate limiting with multiple strategies in Easegress, define distinct policies in the RateLimiter filter, set a default fallback, and bind specific policies to URL rules using `policyRef` so different endpoints can enforce different throttling behaviors.**

The Easegress traffic gateway provides sophisticated rate limiting capabilities through its `RateLimiter` filter, allowing operators to apply distinct throttling strategies to different API endpoints or user groups. By leveraging multiple policies within a single filter instance, you can enforce strict burst limits on sensitive endpoints while maintaining generous throughput for public APIs, all within the `megaease/easegress` open-source framework.

## How the RateLimiter Filter Works

The **RateLimiter** filter in [`pkg/filters/ratelimiter/ratelimiter.go`](https://github.com/megaease/easegress/blob/main/pkg/filters/ratelimiter/ratelimiter.go) implements request throttling using a token-bucket algorithm provided by the underlying `librl` package. When processing traffic, the filter evaluates incoming requests against configured URL rules, binds the appropriate policy to each rule via `bindPolicyToURL`, and creates an isolated `librl.RateLimiter` instance for every unique rule combination.

During request handling, the filter calls `AcquirePermission` on the matched limiter. The request either proceeds immediately, waits for the specified `timeoutDuration`, or receives a **429 Too Many Requests** response if the limit is exceeded.

## Configuring Multiple Rate Limiting Strategies

To implement differentiated rate limiting across your API surface, you must define multiple policies and explicitly reference them in your URL rules.

### Define Distinct Policies

Each policy describes a throttling strategy using three key parameters: `limitForPeriod` (maximum requests), `limitRefreshPeriod` (token refill interval), and `timeoutDuration` (maximum wait time). In [`pkg/filters/ratelimiter/ratelimiter.go`](https://github.com/megaease/easegress/blob/main/pkg/filters/ratelimiter/ratelimiter.go), the filter parses these definitions and validates them during initialization.

### Set a Default Fallback

The `defaultPolicyRef` field specifies which policy to apply when a URL rule omits the `policyRef` attribute. This ensures every matched request undergoes rate limiting even without explicit policy assignment.

### Create URL Rules with Policy References

URL rules match requests by HTTP method, exact path, path prefix, or regex pattern. Each rule optionally includes a `policyRef` that links to one of your defined policies. The `bindPolicyToURL` function (lines 64-73 in [`pkg/filters/ratelimiter/ratelimiter.go`](https://github.com/megaease/easegress/blob/main/pkg/filters/ratelimiter/ratelimiter.go)) resolves these references during filter initialization, falling back to the default policy when `policyRef` is empty.

## Complete Configuration Example

The following YAML configuration demonstrates two distinct strategies: a strict policy for administrative endpoints and a permissive policy for high-traffic public APIs.

```yaml
- name: rateLimiter
  kind: RateLimiter
  policies:
  - name: strict-policy
    timeoutDuration: 1000ms
    limitRefreshPeriod: 5000ms
    limitForPeriod: 2
  - name: permissive-policy
    timeoutDuration: 100ms
    limitRefreshPeriod: 10ms
    limitForPeriod: 30
  defaultPolicyRef: strict-policy
  urls:
  - methods: [GET, POST, PUT, DELETE]
    url:
      regex: ^/admin/.+$
    policyRef: strict-policy
  - methods: [GET, POST]
    url:
      exact: /api/v1/high-traffic
    policyRef: permissive-policy

```

This example, adapted from [`example/config/pipeline-example.yaml`](https://github.com/megaease/easegress/blob/main/example/config/pipeline-example.yaml), creates a token bucket that allows only 2 requests per 5 seconds for admin endpoints, while permitting 30 requests per 10 milliseconds for the specific high-traffic endpoint.

## Implementation Details

Understanding the internal wiring helps troubleshoot configuration issues and optimize performance.

### Policy Binding Mechanism

When the filter initializes, it iterates through URL rules and executes the `bindPolicyToURL` method to attach the correct policy struct to each rule:

```go
func (rl *RateLimiter) bindPolicyToURL(u *URLRule) {
    name := u.PolicyRef
    if name == "" {
        name = rl.spec.DefaultPolicyRef
    }
    for _, p := range rl.spec.Policies {
        if p.Name == name {
            u.policy = p
            break
        }
    }
}

```

*Source: [`pkg/filters/ratelimiter/ratelimiter.go`](https://github.com/megaease/easegress/blob/main/pkg/filters/ratelimiter/ratelimiter.go) lines 64-73.*

### Limiter Initialization

Each URL rule instantiates its own rate limiter via the `createRateLimiter` method, which translates the policy parameters into the underlying library configuration:

```go
func (url *URLRule) createRateLimiter() {
    policy := librl.Policy{
        LimitForPeriod: url.policy.LimitForPeriod,
    }
    if policy.LimitForPeriod == 0 { policy.LimitForPeriod = 50 }
    if d := url.policy.TimeoutDuration; d != "" {
        policy.TimeoutDuration, _ = time.ParseDuration(d)
    } else {
        policy.TimeoutDuration = 100 * time.Millisecond
    }
    if d := url.policy.LimitRefreshPeriod; d != "" {
        policy.LimitRefreshPeriod, _ = time.ParseDuration(d)
    } else {
        policy.LimitRefreshPeriod = 10 * time.Millisecond
    }
    url.rl = librl.New(&policy)
}

```

*Source: [`pkg/filters/ratelimiter/ratelimiter.go`](https://github.com/megaease/easegress/blob/main/pkg/filters/ratelimiter/ratelimiter.go) lines 13-34.*

The core token-bucket algorithm resides in [`pkg/util/ratelimiter/ratelimiter.go`](https://github.com/megaease/easegress/blob/main/pkg/util/ratelimiter/ratelimiter.go), implementing the actual permission acquisition logic that the filter invokes.

## Summary

- **Define multiple policies** in the `RateLimiter` filter to create distinct throttling strategies with varying `limitForPeriod`, `limitRefreshPeriod`, and `timeoutDuration` values.
- **Set a `defaultPolicyRef`** to ensure unmatched URL rules still undergo rate limiting.
- **Reference policies via `policyRef`** in URL rules to bind specific strategies to endpoint patterns, methods, or exact paths.
- **The filter creates isolated limiters** per rule using `bindPolicyToURL` and `createRateLimiter`, enabling fine-grained traffic shaping without cross-contamination between endpoints.

## Frequently Asked Questions

### What happens if a URL rule does not specify a policyRef?

If a URL rule omits the `policyRef` field, the filter automatically uses the policy defined in `defaultPolicyRef`. If neither is specified, the rule may not enforce rate limiting unless the implementation provides internal defaults, though best practice requires explicit configuration.

### Can I use regex patterns to apply different rate limits to API versions?

Yes. The `url.regex` field accepts standard regular expressions, allowing you to match patterns like `^/api/v1/.+$` for version 1 and `^/api/v2/.+$` for version 2, each referencing different policies to enforce version-specific throughput limits.

### How does the timeoutDuration parameter affect client experience?

The `timeoutDuration` specifies how long a request waits for a token to become available before receiving a **429 Too Many Requests** response. Longer durations increase queueing time but improve success rates for bursty traffic, while zero or short durations fail fast during congestion.

### Is there a performance overhead when using many URL rules?

Each URL rule creates an independent `librl.RateLimiter` instance during initialization, so memory usage scales linearly with rule count. However, the lookup operation during request handling uses efficient matching, and the per-rule isolation prevents rate limit contention between different API groups.