Skip to content

RateLimitingMiddleware never disposes PartitionedRateLimiter causing memory leak #66434

@kvantetore

Description

@kvantetore

Is there an existing issue for this?

  • 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-middlewareIncludes: URL rewrite, redirect, response cache/compression, session, and other general middlewaresbugThis issue describes a behavior which is not expected - a bug.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions