← cd ~/blog
~/blog/evm-chain-performance-testing-with-tpser.md

EVM Chain Performance Testing with tpser

EVM Chain Performance Testing with tpser

tpser is a Go CLI for EVM chain performance testing: historical block-range TPS analysis and sustained load generation for any Ethereum-compatible node.

When you're operating or developing on an EVM-compatible blockchain — whether that's Ethereum mainnet, a Layer 2 like Linea, or a private network — you eventually need to answer two questions: how has this chain been performing, and how much load can it actually handle?

These are different problems. Historical analysis needs a block-range scanner that can crunch past data efficiently. Load testing needs a sustained transaction generator that can hammer a node at a configurable rate and measure what breaks first.

tpser is a single Go binary that covers both modes.

Two Modes, One Tool

Mode 1: Block-Range Analyser

The analyser mode scans a range of historical blocks, computes per-block TPS, gas utilisation, and transaction counts, and emits a structured report. This is what you reach for when you want to understand real-world chain behaviour — peak TPS windows, sustained throughput, how busy the chain has been around a specific incident.

tpser analyse \
  --rpc https://rpc.yourchain.example \
  --from 1000000 \
  --to 1001000 \
  --output report.json

The output includes per-block metrics and aggregate statistics:

{
  "block_range": { "from": 1000000, "to": 1001000 },
  "total_transactions": 48291,
  "avg_tps": 15.3,
  "peak_tps": 87.2,
  "avg_gas_utilisation": 0.71
}

This is useful for capacity planning, post-incident reviews, and producing the kind of reproducible benchmarks that are worth including in engineering reports.

Mode 2: Sustained Load Generator

The load generator creates and broadcasts raw EVM transactions at a configurable rate for a set duration. It uses pre-funded accounts to sign transactions, bypasses mempool congestion by constructing nonces manually, and measures actual throughput rather than submitted throughput.

tpser load \
  --rpc https://rpc.yourchain.example \
  --private-key 0xYOURPRIVATEKEY \
  --tps 50 \
  --duration 300s

This drives 50 transactions per second into the target node for five minutes, then reports how many were included in blocks versus how many were dropped or delayed. That delta is what tells you where the bottleneck actually is — the node's ingestion rate, the block production rate, or the network propagation time.

Targeting Any EVM-Compatible Chain

tpser works against any JSON-RPC endpoint that conforms to the Ethereum spec. The --rpc flag accepts HTTP and WebSocket endpoints:

# Mainnet via Infura
tpser analyse --rpc https://mainnet.infura.io/v3/YOUR_KEY --from 19000000 --to 19001000

# Local development node
tpser load --rpc http://localhost:8545 --private-key 0xac0974bec39... --tps 100 --duration 60s

# Layer 2 testnet
tpser load --rpc https://rpc.sepolia.linea.build --private-key 0x... --tps 200 --duration 120s

Automated Slack Reporting

For CI pipelines or scheduled benchmarks, tpser supports Slack webhook integration. Each completed run can post a summary automatically:

tpser analyse \
  --rpc https://rpc.yourchain.example \
  --from 19000000 --to 19001000 \
  --slack-webhook https://hooks.slack.com/services/YOUR/WEBHOOK/URL

This is how the Polygon Edge team used a predecessor of this tool: every deployment triggered a benchmark run, and the Slack report gave engineers immediate visibility into whether the new build had regressed throughput.

What to Look For in Load Test Results

When interpreting load generator output, a few numbers matter most:

Inclusion rate — the ratio of submitted transactions to on-chain inclusions. A rate below 95% under sustained load usually points to mempool backpressure or a misconfigured gas price floor.

Block fullness — if blocks are consistently at 100% gas utilisation during the test, the chain's theoretical maximum TPS is being hit. Back off the load and watch where the ceiling is.

Latency distribution — how long from submission to inclusion? p50, p95, and p99 matter separately. A low p50 with a high p99 often signals intermittent block production issues rather than a throughput ceiling.

Building and Running

tpser is a standard Go module with no CGo dependencies:

git clone https://github.com/ZeljkoBenovic/tpser
cd tpser
go build -o tpser .
./tpser --help

Or pull the latest release binary directly from the GitHub releases page and drop it into your $PATH.

Conclusion

Whether you're benchmarking a new node release, validating infrastructure capacity before a traffic spike, or producing reproducible performance data for a post-mortem, tpser gives you a single tool with no runtime dependencies and a clean CLI interface.

Browse the tpser source on GitHub and run your first EVM chain benchmark.

← prev
EC2 Fleet Command Execution Without Opening SSH
next →
Kubernetes Storage Operations Made Easy with kmon
$ esc
cd ~/ home get blog all posts get projects open-source workloads describe engineer resource spec crash pod CrashLoopBackOff demo get post/easy-mikrotik-backup Mikrotik Backups Made Easy get post/ec2-fleet-commands-without-ssh EC2 Fleet Command Execution Without Opening SSH get post/evm-chain-performance-testing-with-tpser EVM Chain Performance Testing with tpser get post/kubernetes-pvc-snapshot-management-with-kmon Kubernetes Storage Operations Made Easy with kmon get post/teams-direct-routing-without-sbc-hardware Microsoft Teams Direct Routing Without the Hardware SBC get post/veeam-backup-grafana-dashboard Monitoring Veeam B&R with Govein get post/vmware-vcenter-vm-inventory-export-to-excel Exporting VMware vCenter VM Inventory to Excel open job/gombak Go-based automation service for MikroTik router backup management — supports single-device and fleet-wide discovery via L2TP, SSH-based access, configurable retention policies, and system service integration for scheduled unattended backups. open deploy/tsbc Containerised Session Border Controller that bridges SIP/UDP-based PBX systems with Microsoft Teams Direct Routing — orchestrates Kamailio, RTPEngine, and LetsEncrypt TLS to handle signalling and media translation without dedicated SBC hardware. open cronjob/aws-commander CLI tool for fleet-wide remote execution on EC2 instances via AWS SSM Run Command — supports ad-hoc shell commands, script files, and Ansible playbooks, targeting instances by ID or tag without requiring inbound SSH access or open security group rules. open exporter/govein Metrics exporter that queries Veeam Backup & Replication 12+ via its REST API and ships structured job telemetry to InfluxDB 2.0 — ships with a Grafana dashboard template and supports standalone binary, Docker Compose, and Kubernetes Helm deployment. open tool/tpser EVM chain performance testing toolkit with two operating modes — a block-range analyser for historical TPS and gas utilisation reporting, and a sustained load generator for stress-testing nodes at configurable transaction rates over extended durations. open cli/vmex CLI utility that queries VMware vCenter via the vSphere API and exports filtered VM inventory data to formatted Excel workbooks — addressing the limitations of vCenter's native CSV-only export for operational reporting and auditing workflows. open cli/kmon Kubernetes administrative CLI and k9s plugin that automates common storage operations — spins up debug pods from live PVCs, restores volumes from VolumeSnapshots, and generates on-demand or CronJob-scheduled snapshots with configurable snapshot class support.