From b477c6c7521c6bbe11d45c9603116dd8a9cf285e Mon Sep 17 00:00:00 2001
From: Awiteb
Date: Sat, 22 Aug 2026 09:36:37 +0000
Subject: [PATCH] sdk(local_relay): limit the max connection limit
Refs: https://github.com/nostrdevkit/nostr/issues/1460
Signed-off-by: Awiteb
---
nostr-sdk/CHANGELOG.md | 6 ++++++
nostr-sdk/src/local_relay/builder.rs | 9 +++++----
nostr-sdk/src/local_relay/local/inner.rs | 7 +++----
3 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/nostr-sdk/CHANGELOG.md b/nostr-sdk/CHANGELOG.md
index dc65dd5e0..1c9485f5a 100644
--- a/nostr-sdk/CHANGELOG.md
+++ b/nostr-sdk/CHANGELOG.md
@@ -27,6 +27,12 @@
-->
+## Unreleased
+
+### Changed
+
+- local_relay: default connection limit set to 512 (https://github.com/nostrdevkit/nostr/pull/1462)
+
## v0.45.2 - 2026/08/19
### Fixed
diff --git a/nostr-sdk/src/local_relay/builder.rs b/nostr-sdk/src/local_relay/builder.rs
index 5a4905cb7..cee5d91df 100644
--- a/nostr-sdk/src/local_relay/builder.rs
+++ b/nostr-sdk/src/local_relay/builder.rs
@@ -17,6 +17,7 @@ use nostr_database::prelude::*;
use super::local::LocalRelay;
pub(super) const DEFAULT_MAX_PENDING_HANDSHAKES: usize = 128;
+pub(super) const DEFAULT_CONNECTIONS_LIMIT: usize = 512;
pub(super) const DEFAULT_MAX_FILTERS_PER_REQ: usize = 20;
pub(super) const DEFAULT_MAX_EVENT_SIZE: usize = 64 * 1024;
pub(super) const DEFAULT_MAX_QUERY_RESULTS: usize = 500;
@@ -285,7 +286,7 @@ pub struct LocalRelayBuilder {
/// NIP42 options
pub(crate) nip42: Option,
/// Max connections allowed
- pub(crate) max_connections: Option,
+ pub(crate) max_connections: usize,
/// Max WebSocket message size
pub(crate) max_websocket_message_size: usize,
/// Max event size in bytes
@@ -345,7 +346,7 @@ impl Default for LocalRelayBuilder {
auth_events_per_minute: DEFAULT_AUTH_EVENTS_PER_MINUTE,
messages_per_minute: DEFAULT_MESSAGES_PER_MINUTE,
nip42: None,
- max_connections: None,
+ max_connections: DEFAULT_CONNECTIONS_LIMIT,
max_websocket_message_size: DEFAULT_MAX_WEBSOCKET_MESSAGE_SIZE,
max_event_size: DEFAULT_MAX_EVENT_SIZE,
websocket_handshake_timeout: DEFAULT_WEBSOCKET_HANDSHAKE_TIMEOUT,
@@ -448,10 +449,10 @@ impl LocalRelayBuilder {
self
}
- /// Set number of max connections allowed. By default, connections are unlimited.
+ /// Limits the maximum number of concurrent connections. Defaults to 512.
#[inline]
pub fn max_connections(mut self, max: usize) -> Self {
- self.max_connections = Some(max);
+ self.max_connections = max.min(tokio::sync::Semaphore::MAX_PERMITS);
self
}
diff --git a/nostr-sdk/src/local_relay/local/inner.rs b/nostr-sdk/src/local_relay/local/inner.rs
index b2f7544b5..1ac2a49f0 100644
--- a/nostr-sdk/src/local_relay/local/inner.rs
+++ b/nostr-sdk/src/local_relay/local/inner.rs
@@ -113,9 +113,7 @@ impl InnerLocalRelay {
auth_events_per_minute: builder.auth_events_per_minute,
messages_per_minute: builder.messages_per_minute,
pending_handshakes_limit: Arc::new(Semaphore::new(DEFAULT_MAX_PENDING_HANDSHAKES)),
- connections_limit: Arc::new(Semaphore::new(
- builder.max_connections.unwrap_or(Semaphore::MAX_PERMITS),
- )),
+ connections_limit: Arc::new(Semaphore::new(builder.max_connections)),
max_websocket_message_size: builder.max_websocket_message_size,
max_event_size: builder.max_event_size,
websocket_handshake_timeout: builder.websocket_handshake_timeout,
@@ -1655,6 +1653,7 @@ where
#[cfg(test)]
mod tests {
use super::*;
+ use crate::local_relay::DEFAULT_CONNECTIONS_LIMIT;
#[derive(Debug)]
struct RejectWrites;
@@ -1714,7 +1713,7 @@ mod tests {
assert_eq!(relay.pending_handshakes_limit.available_permits(), 128);
assert_eq!(
relay.connections_limit.available_permits(),
- Semaphore::MAX_PERMITS
+ DEFAULT_CONNECTIONS_LIMIT
);
assert_eq!(relay.queries_per_minute, 1_200);
assert_eq!(relay.auth_events_per_minute, 30);