Skip to Content
New: a threat-model-first guide to choosing your network defence, plus the nym-smoldvpn dVPN package and nym-swizzle sender hygiene.
Developersnym-sdkClient Pool Module

Client Pool

Requires the client-pool feature, which is on by default. With default-features = false, add features = ["client-pool"]. See Installation.

The ClientPool keeps a configurable number of MixnetClient instances pre-connected in a background loop, so callers don’t pay the gateway handshake, key generation, and topology fetch cost on the hot path.

How it works

  1. Create the pool with a target reserve size: ClientPool::new(5).
  2. Start the background loop: pool.start(). It immediately begins connecting clients.
  3. Pop a client when needed: pool.get_mixnet_client() returns Some(client) or None if the pool is empty.
  4. Use the client normally: send messages, open streams.
  5. Disconnect the client when done. The background loop notices the pool is below reserve and creates a replacement.

Clients are consumed, not returned. The pool creates new ones to maintain the reserve. If the pool is empty, you can fall back to MixnetClient::connect_new() (slower, but keeps things working).

The NymProxyClient (TcpProxy) uses a ClientPool internally: one client per incoming TCP connection.

Quick example

use nym_sdk::client_pool::ClientPool; use nym_network_defaults::setup_env; #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> { nym_bin_common::logging::setup_tracing_logger(); // Load mainnet network defaults into env vars (required by ClientPool) setup_env(None::<String>); let pool = ClientPool::new(5); // maintain 5 clients in reserve let pool_clone = pool.clone(); tokio::spawn(async move { pool_clone.start().await }); // Get a client when needed if let Some(client) = pool.get_mixnet_client().await { println!("Got client: {}", client.nym_address()); client.disconnect().await; } pool.disconnect_pool().await; Ok(()) }

Further reading

Last updated on