Skip to content

Keep-Alive ​

Reduce latency by reusing HTTP connections instead of establishing new ones for each request.

Overview ​

BlockSprint supports HTTP/1.1 persistent connections (keep-alive). This eliminates the overhead of TCP and TLS handshakes for each request, significantly reducing latency for high-frequency trading.

SettingValue
Idle timeout90 seconds
Max requests per connection1000

Ping Endpoint ​

Use the /ping endpoint to keep connections alive without sending actual requests.

Request ​

GET /ping

Response ​

pong

cURL ​

bash
curl -X GET 'https://fra.blocksprint.io/ping'

Usage ​

Python ​

python
import requests
import threading
import time

session = requests.Session()
ENDPOINT = "https://fra.blocksprint.io/api/v1/YOUR_API_KEY"

# Keep-alive ping every 60 seconds
def keep_alive():
    while True:
        session.get("https://fra.blocksprint.io/ping")
        time.sleep(60)

threading.Thread(target=keep_alive, daemon=True).start()

# Use the same session for all requests
response = session.post(ENDPOINT, json={
    "jsonrpc": "2.0",
    "id": 1,
    "method": "sendTransaction",
    "params": [encoded_tx]
})

JavaScript (Node.js) ​

javascript
// npm install undici
import { Agent, fetch } from "undici";

// Create agent with keep-alive enabled (idle sockets kept for 85 s)
const agent = new Agent({
  keepAliveTimeout: 85_000,
  keepAliveMaxTimeout: 85_000,
  connections: 10,
});

const ENDPOINT = "https://fra.blocksprint.io/api/v1/YOUR_API_KEY";

// Keep-alive ping every 60 seconds
setInterval(async () => {
  await fetch("https://fra.blocksprint.io/ping", { dispatcher: agent });
}, 60000);

// Use the same agent for all requests
async function sendTransaction(encodedTx) {
  const response = await fetch(ENDPOINT, {
    method: "POST",
    dispatcher: agent,
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      jsonrpc: "2.0",
      id: 1,
      method: "sendTransaction",
      params: [encodedTx],
    }),
  });

  return response.json();
}

Rust ​

rust
use reqwest::Client;
use std::time::Duration;

#[tokio::main]
async fn main() {
    // Client with connection pooling (keep-alive by default)
    let client = Client::builder()
        .pool_idle_timeout(Duration::from_secs(90))
        .pool_max_idle_per_host(10)
        .build()
        .unwrap();

    let endpoint = "https://fra.blocksprint.io/api/v1/YOUR_API_KEY";

    // Keep-alive ping task
    let ping_client = client.clone();
    tokio::spawn(async move {
        loop {
            let _ = ping_client
                .get("https://fra.blocksprint.io/ping")
                .send()
                .await;
            tokio::time::sleep(Duration::from_secs(60)).await;
        }
    });

    // Use the same client for all requests
    let response = client
        .post(endpoint)
        .json(&serde_json::json!({
            "jsonrpc": "2.0",
            "id": 1,
            "method": "sendTransaction",
            "params": [encoded_tx]
        }))
        .send()
        .await
        .unwrap();
}

Benefits ​

Without Keep-AliveWith Keep-Alive
TCP handshake (~1 RTT)Reused connection
TLS handshake (~2 RTT)Reused TLS session
~50-150ms overhead~0ms overhead

For high-frequency trading, this can mean the difference between landing a transaction and missing the slot.

Best Practices ​

Ping every 60 seconds ​

Stay well under the 90-second timeout by pinging periodically.

Reuse your HTTP client ​

Don't create new clients per request — reuse sessions/agents/clients to benefit from connection pooling.

Set appropriate pool size ​

Match your concurrency needs by configuring pool sizes (e.g., connections, pool_max_idle_per_host).

Handle reconnects gracefully ​

Be prepared for connections to close after 1000 requests and implement retry/reconnect logic.

Rate Limit ​

The /ping endpoint has no rate limit and does not count against your API quota.