dotnet / dotnet/aspnetcore

RateLimitingMiddleware never disposes PartitionedRateLimiter causing memory leak

Open
#66,434 1 comment 2 reactions 0 assignees View on GitHub
area-middleware bug feature-rate-limit
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

### Is there an existing issue for this?

- [x] I have searched the existing issues

### Describe the bug

`RateLimitingMiddleware` creates a `PartitionedRateLimiter` in the constructor. The `DefaultPartitionedRateLimiter` implementation uses a Timer to implement a Heartbeat for managing rate limiting. `RateLimitingMiddleware` does not implement IDisposable, and currently never disposes the created `PartitionedRateLimiter`. This cases a memory leak when middleware pipelines are expected to be temporary.

My use case for this is a multitenant setup, where a `ServiceProvider` and a middleware pipeline is set up per tenant, and I want to be able to "recycle" tenants without restarting the entire app.

### Expected Behavior

When RateLimitingMiddleware is no longer needed, it should remove all calbacks to itself to allow it to be garbage collected.

I believe a realtively easy fix is to migrate `RateLimitingMiddleware` to an `IMiddleware`-type middleware, implement IDisposable, and dispose the constructed `PartitionedRateLimiter` owned by the middleware. Callers using `RateLimiterOptions.GlobalLimiter` will have to manage the lifecycle of the supplied `PartitionedRateLimiter` manually.

### Steps To Reproduce

_No response_

### Exceptions (if any)

_No response_

### .NET Version

11.0.100-preview.4.26210.111

### Anything else?

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.