shred-stats is an open-source Go benchmark tool for comparing the arrival performance of multiple Solana Shred streams on the same host.
It receives raw Shred packets over UDP, parses the Shred identity, records the earliest local arrival time for each Shred, and reports one-minute first-arrival and relative-latency statistics. Results are written to a rotating log file and exported as Prometheus metrics.
This repository is a measurement tool—not a Shred reconstruction or transaction-decoding client. For receiving, recovering, deshredding, and decoding BlockRazor Shreds, see
BlockRazorinc/shreds-subscribe.
| Measurement | Meaning |
|---|---|
| Received packets | Number of valid Solana Shred UDP packets accepted from the target and non-target sources during the last minute |
| First-arrival share | Which source first delivered each observed Shred identity during the last minute |
| Target lead time | base arrival time - target arrival time, calculated only when the target arrived first |
| Target difference | base arrival time - target arrival time, calculated whenever both sources delivered the same Shred |
| Quantiles | P1, P5, P10, P25, P50, P75, P80, P90, P95, and P99 for the one-minute sample window |
The comparison key used by the current implementation is:
slot:index
The receive timestamp is captured locally immediately after the UDP read. Packets that fail the subsequent Shred-header validation are discarded and do not enter the statistics.
flowchart LR
T["Target Shred stream"] -->|UDP| P1["Target port"]
B1["Base stream A"] -->|UDP| P2["Base port A"]
B2["Base stream B"] -->|UDP| P3["Base port B"]
P1 --> R["shred-stats"]
P2 --> R
P3 --> R
R --> V["Validate variant, size, slot, and index"]
V --> W["One-minute comparison window"]
W --> L["traffic_stats.log"]
W --> M["Prometheus /metrics"]
All streams are timestamped by the same process and system clock. This avoids introducing cross-host clock synchronization error into the comparison. For a fair test, deliver every stream under comparison to the same server and keep the network path, host load, UDP buffers, and test duration as consistent as possible.
Benchmark results are specific to the test region, network path, server, time window, and source configuration. They should not be treated as universal latency guarantees.
- Go 1.24.1 or later, as declared by
go.mod - A host that can receive inbound UDP traffic on every selected port
- At least two Solana Shred streams for a relative comparison
- An unused TCP address for the Prometheus endpoint; default:
:2112
The UDP listener uses low-level IPv4 sockets, binds to 0.0.0.0, and requests a 7,500,000-byte receive buffer for each configured port.
git clone https://github.com/BlockRazorinc/shred-stats.git
cd shred-stats
go build -trimpath -ldflags="-s -w" -o shred-stats .Run the binary from the repository root because the current logger loads logger/logo.txt using a relative path.
Configure each provider to send its Shred stream to a distinct UDP port on the benchmark host. For BlockRazor Shred Stream:
- Create a Shred Stream in the BlockRazor Portal.
- Set the destination to the benchmark host's public
IP:portordomain:port. - Select the BlockRazor region closest to the benchmark host.
- Allow that UDP port through the host firewall and cloud security group.
Use a different destination port for the comparison stream unless you plan to classify streams by source IP.
Treat UDP port 19001 as the target and port 19002 as the base:
./shred-stats \
--target-port 19001 \
--port 19002 \
--metrics-addr 127.0.0.1:2112Add --port again for each additional base stream:
./shred-stats \
--target-port 19001 \
--port 19002 \
--port 19003In port-based mode:
--target-portis required.- Every
--portvalue is treated as a separately named base, using the port number as its name. - Do not repeat the target port under
--port; the program appends and binds it automatically.
Statistics are emitted after the first one-minute collection window and then once per minute.
Address-filter mode is useful when provider identity must be determined from both the UDP packet's source IPv4 address and its local destination port.
Enable it with --is-filter-addr:
./shred-stats \
--port 19001 \
--port 19002 \
--is-filter-addr \
--target-ip-filters 203.0.113.10-19001 \
--base-ip-filters jito:198.51.100.20-19002 \
--metrics-addr 127.0.0.1:2112Replace the documentation-only IP addresses above with the actual packet source addresses observed on your host.
Target filters use:
<source-ip>-<destination-port>
Multiple target filters are comma-separated:
--target-ip-filters 203.0.113.10-19001,203.0.113.11-19001Base filters use:
<base-name>:<source-ip>-<destination-port>
Multiple base filters are comma-separated:
--base-ip-filters jito:198.51.100.20-19002,provider-b:192.0.2.30-19003In address-filter mode, every destination port must still be supplied with --port; --target-port is not used to create a listener in this mode. Packets that match neither a target nor a named base are classified as other.
First seen shred in 1min: {From:targets, Nums:105849, Percent:85.9%}, {From:others, Nums:0, Percent:0.0%}, {From:jito, Nums:17344, Percent:14.1%}
For each slot:index observed during the window, the program compares the earliest target, base, and unclassified arrival timestamps. The count and percentage show which source was observed first by this process.
Target-led shred lead time (n=105849) against jito: ...
This distribution contains only samples where the target arrived before the named base:
lead = base arrival time - target arrival time
All values in this set should therefore be positive. n is the number of matched, target-leading observations in the window.
Target-diff shred diff time (n=123161) against jito: ...
This distribution includes every Shred delivered by both the target and the named base:
difference = base arrival time - target arrival time
- Positive value: the target arrived earlier.
- Negative value: the base arrived earlier.
- Zero or near zero: both were observed at approximately the same time.
The current implementation sorts durations in descending order before selecting quantiles. Consequently, P1 is near the high end of the measured values and P99 is near the low end—the reverse of the more common ascending-percentile convention.
Compare runs using the tool's own convention consistently. If you require conventional percentiles, change the sort order in computeQuantiles before producing comparable results.
By default, benchmark output is written to:
./traffic_stats.log
Log rotation defaults:
| Setting | Default |
|---|---|
| Maximum file size | 100 MB |
| Maximum backups | 10 |
| Maximum age | 10 days |
To send logger output to stdout instead of the log file, use:
./shred-stats \
--target-port 19001 \
--port 19002 \
--log-file-level stdoutWith --log-level debug, the program can additionally create per-sample difference logs named like traffic_diff_detail_YYYY-MM-DD HH:MM.log for bases with target-led samples. Debug output may be large under production traffic.
The metrics endpoint is available at:
http://<metrics-addr>/metrics
The default bind address is :2112, which exposes the endpoint on all interfaces. Prefer 127.0.0.1:2112 unless remote scraping is required.
| Metric | Type | Labels | Unit / meaning |
|---|---|---|---|
shred_stream_first_shred |
Gauge | src |
First-arrival count in the last completed one-minute window |
shred_stream_shred_lead_quantile |
Gauge | base, quantile |
Target-only lead quantile in microseconds |
shred_stream_shred_diff_quantile |
Gauge | base, quantile |
Signed target/base difference quantile in microseconds |
For shred_stream_first_shred, the current implementation exports the target under src="relay", unmatched traffic under src="other", and each named base under its configured name.
Example scrape:
curl http://127.0.0.1:2112/metricsExample Prometheus configuration:
scrape_configs:
- job_name: shred-stats
scrape_interval: 15s
static_configs:
- targets: ["127.0.0.1:2112"]The gauges describe the last completed application window; they are not cumulative counters. Raw target/other receive totals are logged but are not currently exported as Prometheus metrics.
| Flag | Required | Default | Description |
|---|---|---|---|
--port <port> |
Yes | — | Base/listening UDP port; repeat for multiple ports |
--target-port <port> |
Port mode | — | Target UDP port in non-filter mode |
--is-filter-addr |
No | false |
Classify packets by source IP plus destination port |
--target-ip-filters <filters> |
Filter mode | — | Comma-separated target filters in IP-port format |
--base-ip-filters <filters> |
No | — | Comma-separated named base filters in name:IP-port format |
--metrics-addr <address> |
No | :2112 |
Prometheus HTTP listen address |
--log-level <level> |
No | info |
Logger level, such as trace, debug, or info |
--log-file-level <value> |
No | info |
Set to stdout to redirect logger output to stdout |
--log-max-size <MB> |
No | 100 |
Maximum log file size before rotation |
--log-max-backups <count> |
No | 10 |
Maximum number of rotated log files |
--log-max-age <days> |
No | 10 |
Maximum age of rotated log files |
Show the version-specific CLI help with:
./shred-stats --help- Only UDP packets that parse as supported Legacy or Merkle Solana Shreds are measured.
- The tool parses only enough of the Shred header to validate the packet and read its slot and index. It does not perform FEC recovery, deshredding, block reconstruction, or transaction decoding.
- First-arrival records use
slot:indexas their identity. The Shred variant is not included in the current comparison key. - The raw receive totals count accepted packets, while first-arrival results collapse observations into one record per
slot:indexwithin the window. - UDP is connectionless and may drop, duplicate, or reorder packets. Tune the host and network for sustained traffic before interpreting results.
- Latency is measured at the application receive point. Provider processing, Internet routing, kernel scheduling, socket buffering, host load, and virtualization can all affect it.
- Metrics for a base's lead and difference quantiles are refreshed only for windows containing at least one target-leading sample against that base.
- In the current implementation, an address-filter window containing a
slot:indexseen only as unmatchedothertraffic can reach a nil-timestamp edge case during first-arrival aggregation. Use verified, exhaustive filters for benchmark sources and validate the behavior before unattended operation. - Metrics are unauthenticated. Restrict the metrics listener with a local bind, firewall, or reverse proxy.
- Place the benchmark host in the intended test region and use the same host for all streams.
- Verify provider source IPs with
tcpdumpor an equivalent packet-capture tool before enabling address filters. - Open only the required UDP ports and restrict source ranges where provider addresses are stable.
- Keep the Prometheus endpoint private unless external access is explicitly required.
- Confirm that each UDP port is free before launch.
- Monitor packet drops, CPU load, memory pressure, and NIC saturation during the test.
- Run multiple comparable windows and preserve the test region, time, host type, and stream configuration with the results.
- Treat sample output in this README as format illustration, not current service performance.
On Linux, inspect UDP receive errors and buffer limits with tools such as:
netstat -su
sysctl net.core.rmem_default net.core.rmem_maxYou are running in port-based mode without --target-port. Add the target port or enable address-filter mode with complete target and base filters.
Another process already owns the UDP port, or the target port was also repeated under --port. Stop the conflicting listener or select another port.
- Confirm that the provider is sending to the correct public IP and UDP port.
- Check cloud security groups, host firewall rules, NAT, and port forwarding.
- Capture the port with
tcpdumpto distinguish network delivery problems from application parsing problems. - Enable
--log-level debugto inspect rejected packet errors.
The source IP or destination port in the filter does not match the packet as observed by the benchmark host. Verify the actual source address and remember that the filter suffix is the local destination port, not the sender's ephemeral UDP source port.
Check whether the TCP metrics address is already in use and whether the requested bind address exists on the host. UDP Shred ports and the TCP Prometheus port are separate listeners.
.
├── main.go # CLI, listeners, logging, and metrics server
├── udp/ # Low-level UDP socket implementation
├── solana/ # Partial Solana Shred parsing and validation
├── stats/ # One-minute first-arrival and latency statistics
├── metrics/ # Prometheus metric definitions
├── logger/ # Console branding and rotating logs
└── cache/ # Expiring key-cache implementation
- BlockRazor Solana Shred Stream documentation
- BlockRazor Solana infrastructure
- BlockRazor Solana Shred Stream benchmark methodology
- BlockRazor Shred subscription and reconstruction example
This tool is provided for engineering evaluation. Observed latency and first-arrival results depend on the selected providers, regions, routes, host configuration, traffic conditions, and test window. Validate the methodology against your own production requirements before making infrastructure decisions.