Skip to content

feat: add rate limiter#1750

Merged
drahnr merged 27 commits intonextfrom
bernhard-feat-add-rate-limiter
Mar 9, 2026
Merged

feat: add rate limiter#1750
drahnr merged 27 commits intonextfrom
bernhard-feat-add-rate-limiter

Conversation

@drahnr
Copy link
Contributor

@drahnr drahnr commented Mar 4, 2026

Adds a rate-limiter with quotas using tower_governor and tower::limit::GlobalConcurrencyLimitLayer.

Done in scope of our recent fd consumption, generally a useful thing to do.

Makes all parameters configurable and group them into GrpcOptions and moves them to miden-node-utils to avoid duplication, similarly for limiting layer setup helpers.

@drahnr drahnr force-pushed the bernhard-feat-add-rate-limiter branch from 3ea5ce1 to 558e109 Compare March 5, 2026 16:25
@drahnr drahnr requested a review from Mirko-von-Leipzig March 5, 2026 16:36
@drahnr drahnr marked this pull request as ready for review March 5, 2026 16:36
// TODO double check how to address proxy rate limiting based on i.e. `X-Real-IP`.
request
.metadata_mut()
.insert("forwarded", format!("for={addr}").try_into().unwrap());
Copy link
Collaborator

@sergerad sergerad Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we shouldn't panic here right? this is a callback for every request?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a callback per request, unless someone manages to inject a broken/malicious IP in the Linux Kernel and manage to pop it up in our end, it's virtually impossible to break this invariant.

Since we're using SmartIPKeyExtractor* we might get away without this. It's here for ensuring we have a fallback

Copy link
Collaborator

@Mirko-von-Leipzig Mirko-von-Leipzig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unclear on whether we want to apply any gRPC options to our internal services at all. I would tend to say no?

///
/// If the handler takes longer than this duration, the server cancels the call.
pub grpc_timeout: Duration,
pub grpc_options: GrpcOptionsInternal,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doc comment is inaccurate now. We also ignore the max connections setting then?

Comment on lines +32 to +38
/// Number of global concurrent connections.
#[arg(
long = "grpc.max_global_connections",
default_value_t = DEFAULT_MAX_GLOBAL_CONNECTIONS,
value_name = "MAX_GLOBAL_CONNECTIONS"
)]
pub max_global_concurrent_connections: u64,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think global is confusing -- this is just the maximum number of connections?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to _concurrent_ if that's any better, open to suggestions

use tonic::service::Interceptor;
use tonic::{Request, Status};

// Extracts the IP for `Governor`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its unclear in this context what a Governor is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extended doc comment

}
});

let concurrency_semaphore = grpc::concurrency_semaphore(self.grpc_options);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is incorrect. We don't want to share concurrency between these because it means external RPC requests can DoS our internal requests. I still don't think we want to apply any limits internally at all.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed, only limiting the RPC component now

@drahnr
Copy link
Contributor Author

drahnr commented Mar 9, 2026

I'd tend to say a global connection limit to self-protect each service is a good thing in general. It's a trade-off of risks, and I don't think there is a good answer.

I removed all limits for internal services again.

@Mirko-von-Leipzig
Copy link
Collaborator

I'd tend to say a global connection service to self-protect each service is a good thing in general. It's a trade-off of risks, and I don't think there is a good answer.

I do agree; but at the moment we don't have any good idea on numbers.

@drahnr drahnr merged commit 07dfd3d into next Mar 9, 2026
19 checks passed
@drahnr drahnr deleted the bernhard-feat-add-rate-limiter branch March 9, 2026 16:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants