All Docs

Best Practices

This guide covers production deployment recommendations for receiving ShredStream.com data reliably at scale. Following these practices will minimize packet loss, reduce latency, and ensure your shred processing pipeline stays healthy.

UDP Buffer Sizing

The single most common source of shred loss is an undersized kernel receive buffer. When shreds arrive faster than your application reads them, the kernel drops packets silently. Set your receive buffer to at least 25 MB:

# Set at runtime
sudo sysctl -w net.core.rmem_max=26214400
sudo sysctl -w net.core.rmem_default=26214400
# Persist across reboots - add to /etc/sysctl.conf
net.core.rmem_max=26214400
net.core.rmem_default=26214400
# Verify
sysctl net.core.rmem_max

Note on Linux buffer doubling

Linux internally doubles the value you pass to SO_RCVBUF (half is reserved for kernel bookkeeping). If you request 25 MB, getsockopt may report ~50 MB. This is expected.

Monitoring Your Stream

Track key metrics to detect degradation early. The most important things to monitor are:

  • Shred rate — Expected: 500-5,000 shreds/sec depending on network load
  • Kernel drops — Nonzero drops mean your buffer or processing is too slow
  • Slot gap — Compare the latest slot in your stream vs. a Solana RPC to measure freshness
  • Process CPU/memory — Ensure your listener is not saturating resources

Monitor kernel-level UDP drops on Linux by reading /proc/net/udp or using ss:

bash
# Show UDP socket statistics including drops
ss -u -a -n | head -20
# Monitor drops over time for a specific port
watch -n 1 'cat /proc/net/udp | grep 1F41' # 1F41 = hex for port 8001
# netstat summary - look for "packet receive errors"
netstat -su

Here is an example monitoring loop that logs throughput and checks for slot gaps:

python
import socket
import struct
import time
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 26_214_400)
sock.bind(("0.0.0.0", 8001))
count = 0
last_slot = 0
last_report = time.monotonic()
while True:
data, _ = sock.recvfrom(1280)
count += 1
# Parse slot from shred header (bytes 65-73, little-endian u64)
if len(data) >= 73:
slot = struct.unpack_from("<Q", data, 65)[0]
if slot > last_slot:
last_slot = slot
now = time.monotonic()
if now - last_report >= 10.0:
rate = count / (now - last_report)
print(f"[monitor] {rate:.0f} shreds/sec | latest slot: {last_slot}")
count = 0
last_report = now

Redundancy and Failover

For mission-critical deployments (e.g., MEV bots, liquidation engines), run redundant streams:

  • Multi-region streams — Activate streams in two or more regions and deduplicate by shred signature. The first copy to arrive wins.
  • Long-term commitments — Use the duration multiplier to lock in longer subscriptions (up to 24 months) at discounted rates. Combine with multi-region for maximum reliability and savings.
  • Hot standby servers — Maintain a second server with the same listener. If the primary goes down, update the IP via the API.
  • IP failover script — Automate IP switching when your monitoring detects packet loss above a threshold.
python
import requests
import time
API_KEY = "ss_live_abc123..."
BASE_URL = "https://api.shredstream.com/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
PRIMARY_IP = "203.0.113.42"
FAILOVER_IP = "198.51.100.10"
PORT = 8001
STREAM_ID = None
def activate(ip: str) -> str:
resp = requests.post(
f"{BASE_URL}/activate",
headers=HEADERS,
json={"ip": ip, "port": PORT, "region": "us-east"},
)
resp.raise_for_status()
return resp.json()["stream_id"]
def deactivate(stream_id: str):
requests.post(
f"{BASE_URL}/deactivate",
headers=HEADERS,
json={"stream_id": stream_id},
)
def check_health(stream_id: str) -> float:
resp = requests.get(
f"{BASE_URL}/status",
headers=HEADERS,
params={"stream_id": stream_id},
)
metrics = resp.json()["streams"][0]["metrics"]
return metrics["packet_loss_pct"]
# Main failover loop
STREAM_ID = activate(PRIMARY_IP)
current_ip = PRIMARY_IP
while True:
time.sleep(30)
loss = check_health(STREAM_ID)
if loss > 1.0: # More than 1% packet loss
failover_ip = FAILOVER_IP if current_ip == PRIMARY_IP else PRIMARY_IP
print(f"High loss ({loss}%), switching to {failover_ip}")
deactivate(STREAM_ID)
STREAM_ID = activate(failover_ip)
current_ip = failover_ip

Error Handling

Your UDP listener should be resilient to malformed or truncated packets. Because UDP is connectionless, you will occasionally receive packets that are not valid shreds (e.g., port scanners, stale routes). Always validate before processing:

python
import socket
import struct
SHRED_MIN_SIZE = 88 # Minimum valid shred (header only)
SHRED_MAX_SIZE = 1280 # Maximum shred packet size
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 26_214_400)
sock.bind(("0.0.0.0", 8001))
while True:
data, addr = sock.recvfrom(2048) # Read extra to detect oversized
# Validate packet size
if len(data) < SHRED_MIN_SIZE or len(data) > SHRED_MAX_SIZE:
continue # Skip invalid packets
# Validate shred variant byte (offset 64)
variant = data[64]
# Data shreds: variant & 0xF0 == 0xa0
# Coding shreds: variant & 0xF0 == 0x50
if variant & 0xF0 not in (0xa0, 0x50):
continue # Not a valid shred type
# Parse slot (offset 65, 8 bytes LE)
slot = struct.unpack_from("<Q", data, 65)[0]
# Process the validated shred
process_shred(slot, data)

Reconnection Strategies

Unlike TCP, UDP does not have a "connection" to lose. However, your stream can stop delivering if your subscription expires, your IP changes, or infrastructure maintenance occurs. Implement these strategies:

1. Idle Timeout Detection

If no packets arrive for 30 seconds during normal Solana operation, something is wrong. Use a timeout on your receive call to detect this:

import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 26_214_400)
sock.settimeout(30.0) # 30-second timeout
sock.bind(("0.0.0.0", 8001))
while True:
try:
data, addr = sock.recvfrom(1280)
process_shred(data)
except socket.timeout:
print("WARNING: No shreds received for 30s, checking stream status...")
# Call GET /status to verify stream is active
# Re-activate if needed

2. Periodic Health Checks

Run a background thread that polls the GET /status endpoint every 60 seconds. If the stream status changes from active to expired, trigger your renewal or alerting workflow.

3. Exponential Backoff for Re-activation

When re-activating a stream after an error, use exponential backoff to avoid hammering the API:

python
import time
import requests
def activate_with_backoff(ip, port, region, api_key, max_retries=5):
delay = 1.0
for attempt in range(max_retries):
try:
resp = requests.post(
"https://api.shredstream.com/v1/activate",
headers={"Authorization": f"Bearer {api_key}"},
json={"ip": ip, "port": port, "region": region},
timeout=10,
)
resp.raise_for_status()
return resp.json()
except requests.RequestException as e:
print(f"Attempt {attempt + 1} failed: {e}")
if attempt < max_retries - 1:
time.sleep(delay)
delay = min(delay * 2, 60) # Cap at 60 seconds
raise RuntimeError("Failed to activate stream after max retries")

Performance Tips

  • Pin your receiver to a CPU core. On Linux, use taskset or isolcpus to prevent the scheduler from migrating your process.
  • Use a dedicated NIC queue. With RSS (Receive Side Scaling), direct all traffic on your shred port to a single queue for cache locality.
  • Avoid allocations in the hot path. Pre-allocate buffers and reuse them. In Rust, this means using a fixed [u8; 1280] buffer, not a Vec.
  • Separate receive and processing. Use a ring buffer or channel between the receive thread and processing threads to decouple packet ingestion from business logic.
  • Consider recvmmsg (Linux). Read multiple packets in a single system call to reduce syscall overhead under high throughput.
rust
use std::net::UdpSocket;
use std::sync::mpsc;
use std::thread;
fn main() -> std::io::Result<()> {
let socket = UdpSocket::bind("0.0.0.0:8001")?;
socket.set_recv_buffer_size(26_214_400)?;
// Channel to decouple receive from processing
let (tx, rx) = mpsc::sync_channel::<Vec<u8>>(10_000);
// Receiver thread - hot path, minimal allocations
let recv_handle = thread::spawn(move || {
let mut buf = [0u8; 1280];
loop {
if let Ok((len, _)) = socket.recv_from(&mut buf) {
let _ = tx.send(buf[..len].to_vec());
}
}
});
// Processing thread - can do heavier work here
let proc_handle = thread::spawn(move || {
let mut count: u64 = 0;
while let Ok(shred) = rx.recv() {
count += 1;
// Parse and process shred data
if count % 10_000 == 0 {
println!("Processed {} shreds", count);
}
}
});
recv_handle.join().unwrap();
proc_handle.join().unwrap();
Ok(())
}
ShredStream.com — Fastest Solana Shred Streaming