npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@geeklad/solana-multi-rpc

v1.0.0

Published

A drop-in replacement for the @solana/web3.js Connection that uses multiple RPCs

Readme

@geeklad/solana-multi-rpc

A drop-in replacement for the @solana/web3.js Connection class that transparently spreads requests across multiple RPC endpoints with per-connection rate limiting and automatic retry logic.

Features

  • Drop-in replacement — implements the full Connection interface via ES Proxy; swap it in without changing any call sites
  • Smart throttle-aware routing — tracks each endpoint's sliding-window request budget and routes to the next available connection
  • Automatic retries — retries historical/archival methods (getBlock, getSignaturesForAddress, etc.) on a different RPC when one fails or returns empty results
  • Piling prevention — pending request counts are updated synchronously before any await, so concurrent callers always see accurate queue depth
  • Subscription passthrough — subscription methods (onAccountChange, onSlotChange, …) are forwarded to the first connection

Installation

npm install @geeklad/solana-multi-rpc

Quick Start

import MultiRpcConnection from "@geeklad/solana-multi-rpc";
import type { MultiRpcConnectionConfig } from "@geeklad/solana-multi-rpc";

const configs: MultiRpcConnectionConfig[] = [
    {
        endpoint: "https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY",
        throttleOptions: { maxRequests: 10, timeWindowMs: 1000 },
        commitment: "confirmed",
    },
    {
        endpoint: "https://example.quicknode.pro/YOUR_ENDPOINT_TOKEN/",
        throttleOptions: { maxRequests: 5, timeWindowMs: 1000 },
        commitment: "confirmed",
    },
    {
        endpoint: "https://api.mainnet-beta.solana.com",
        throttleOptions: { maxRequests: 2, timeWindowMs: 1000 },
        commitment: "confirmed",
    },
];

const connection = new MultiRpcConnection(configs, {
    maxRetries: 3,
    retryDelayMs: 500,
});

// Use exactly like a normal Connection
const slot = await connection.getSlot();
const balance = await connection.getBalance(myPublicKey);

See examples/usage.ts for a full working example.

API

MultiRpcConnectionConfig

Extends @solana/web3.js ConnectionConfig with two required fields:

| Field | Type | Description | |---|---|---| | endpoint | string | RPC HTTP URL | | throttleOptions | object | Per-connection rate-limit budget (see sub-fields below) |

throttleOptions sub-fields:

| Field | Type | Description | |---|---|---| | maxRequests | number | Max requests allowed per time window | | timeWindowMs | number | Rolling window duration in milliseconds |

All standard ConnectionConfig fields (commitment, wsEndpoint, httpHeaders, etc.) are also supported and forwarded to the underlying Connection.

new MultiRpcConnection(configs, options?)

| Parameter | Type | Default | Description | |---|---|---|---| | configs | MultiRpcConnectionConfig[] | — | One or more RPC configurations (at least one required) | | options.maxRetries | number | 3 | Max retry attempts for retryable methods | | options.retryDelayMs | number | 1000 | Delay between retry attempts in milliseconds | | options.logLevel | LogLevel | "warn" | Built-in log filter level (see Logging) | | options.logger | Logger | — | Custom logger instance; overrides logLevel (see Logging) |

Instance properties

| Property | Type | Description | |---|---|---| | endpoints | string[] | All configured RPC endpoint URLs | | connectionCount | number | Number of configured connections | | rpcEndpoint | string | Human-readable summary, e.g. MultiRPC[url1, url2] |

Routing Behavior

On each call the router:

  1. Finds the first immediately-available connection (estimated wait = 0 ms), starting from the current round-robin position.
  2. If all connections are throttled, picks the one with the shortest estimated wait and logs the wait time.

The estimated wait accounts for both active requests within the current window and requests already queued ahead in the pending backlog.

Retry Behavior

The following methods are automatically retried across different RPC endpoints on failure or empty results:

  • getBlock
  • getBlocks
  • getSignaturesForAddress
  • getTransaction
  • getParsedTransaction
  • getParsedTransactions

Errors that trigger a retry include network errors, timeouts, rate-limit responses, server errors, and connection resets. Non-retryable errors (e.g. invalid parameters) are thrown immediately.

getSignaturesForAddress additionally retries when a response is empty — useful when a provider has insufficient transaction history.

Logging

MultiRpcConnection includes a built-in logger with four levels:

| Level | What is emitted | |---|---| | "debug" | Per-request RPC selection, retry progress, throttle waits | | "warn" | RPC failures, empty-result retries (default) | | "error" | Non-retryable errors, all-RPCs-exhausted failures | | "silent" | Nothing |

The default level is "warn" — noisy debug messages are suppressed out of the box. Disabled levels are pure no-ops (zero overhead; no string formatting or allocations).

Changing the log level

const connection = new MultiRpcConnection(configs, {
    logLevel: "debug",   // surface per-request routing and retry details
});

Using a custom logger (pino, winston, etc.)

Pass any object that implements debug(), warn(), and error() methods. When a custom logger is provided, logLevel is ignored — configure filtering on your logger directly.

import pino from "pino";

const logger = pino({ level: "warn" });

const connection = new MultiRpcConnection(configs, { logger });
import winston from "winston";

const logger = winston.createLogger({
    level: "warn",
    transports: [new winston.transports.Console()],
});

const connection = new MultiRpcConnection(configs, { logger });

Silencing all output

const connection = new MultiRpcConnection(configs, {
    logLevel: "silent",
});

Subscriptions

Subscription methods (onAccountChange, onProgramAccountChange, onSlotChange, and the corresponding remove* methods) are always routed to the first configured connection. A debug-level message is logged when this happens.

Building

npm run build   # compiles TypeScript to ./dist

License

Apache-2.0