From cf193abfd924110bc9bddd2e1e9e605b87b94007 Mon Sep 17 00:00:00 2001 From: "shakespeare.diy" Date: Tue, 17 Feb 2026 03:18:33 -0600 Subject: [PATCH] Route reads to a single relay (round-robin) for fast EOSE resolution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously reqRouter sent every query to all 3 read relays, meaning NPool.query() had to wait for all relays to coordinate before resolving. The slowest relay dictated the feed speed. Now reads go to one relay at a time, rotating round-robin across the configured read relays. Each query resolves as soon as that single relay sends EOSE — no waiting on the other two. Publishing still fans out to all write relays. Co-authored-by: shakespeare.diy --- src/components/NostrProvider.tsx | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/components/NostrProvider.tsx b/src/components/NostrProvider.tsx index 2b8a7efb..5295fb84 100644 --- a/src/components/NostrProvider.tsx +++ b/src/components/NostrProvider.tsx @@ -26,6 +26,9 @@ const NostrProvider: React.FC = (props) => { queryClient.invalidateQueries({ queryKey: ['nostr'] }); }, [config.relayMetadata, queryClient]); + // Round-robin index for distributing reads across relays + const rrIndex = useRef(0); + // Initialize NPool only once if (!pool.current) { pool.current = new NPool({ @@ -35,26 +38,26 @@ const NostrProvider: React.FC = (props) => { reqRouter(filters: NostrFilter[]) { const routes = new Map(); - // Route to all read relays + // Pick a single read relay (round-robin) so queries resolve on first EOSE const readRelays = relayMetadata.current.relays .filter(r => r.read) .map(r => r.url); - for (const url of readRelays) { - routes.set(url, filters); + if (readRelays.length > 0) { + const idx = rrIndex.current % readRelays.length; + rrIndex.current = idx + 1; + routes.set(readRelays[idx], filters); } return routes; }, eventRouter(_event: NostrEvent) { - // Get write relays from metadata + // Publish to all write relays const writeRelays = relayMetadata.current.relays .filter(r => r.write) .map(r => r.url); - const allRelays = new Set(writeRelays); - - return [...allRelays]; + return [...new Set(writeRelays)]; }, }); }