Benchmark Methodology & Performance
Empirical evaluation comparing Krabka against Strimzi (Apache Kafka on OpenJDK 21) across memory working set, cold-start time, saturated throughput, and tail latency.
Evaluation Philosophy & Goals
Krabka is engineered in native Rust to eliminate JVM runtime overhead, garbage collection pauses, and multi-gigabyte memory footprints in streaming architectures. To validate these characteristics, all macro-benchmarks follow four strict principles:
- Identical Hardware & Topology: Both Krabka and Apache Kafka (Strimzi) run on identical Kubernetes clusters and GCP virtual machines.
- Identical Storage Media: Direct I/O write-ahead logs backed by local NVMe SSDs (ext4 formatted).
- Identical Load Driver: A shared Rust load generator (
bench-driver) speaking standard Apache Kafka wire protocol executes unmodified against both targets. - Coordinated-Omission-Free Latency: Latencies are tracked via HdrHistogram using send timestamps embedded in payload headers rather than client send loops.
Test Environment Topology
All comparative benchmarks are executed against dedicated cloud infrastructure with fixed hardware allocation:
- Compute Hardware: 3x GCP c3-standard-8 instances (8 vCPUs Intel Xeon, 32 GB RAM per node).
- Storage Subsystem: Local NVMe SSD formatted with ext4, utilizing Direct I/O asynchronous write-ahead logs.
- Benchmark Suite: Industry-standard OpenMessaging Benchmark (OMB) and
bench-driverexecuting sustained workloads from 50,000 to 500,000 msg/sec. - Software Baseline: Krabka (native Rust, KRaft consensus) evaluated side-by-side against Strimzi 1.0 running Apache Kafka 4.3 (KRaft, OpenJDK 21).
Memory Working Set Footprint (RSS)
In production Kubernetes deployments, memory capacity and pod eviction decisions are governed by cgroup limits. We measure container_memory_working_set_bytes through Prometheus scrapers during steady-state produce and fanout consumption workloads.
mmap. We collect JMX metrics (jvm_memory_bytes_used) separately to verify heap versus off-heap consumption against Krabka's direct user-space allocation model.
How Krabka Achieves 114.2 MiB Working Set
Krabka operates at a fraction of JVM Kafka's memory footprint due to three architectural design decisions:
- Zero-Copy Buffer Slicing: Slices of byte buffers (
bytes::Bytes) pass through the network I/O layer, log segment appends, and consumer dispatch pipelines without memory duplication or re-allocation. - Deterministic Deallocation: Memory is immediately reclaimed when reference counts hit zero. There are no background GC compaction passes, heap fragmentation margins, or speculative memory reservations.
- Compact Memory Representation: Rust structs avoid the 12-to-16-byte object header overhead, pointer indirection, and boxed primitive structures inherent to JVM runtimes.
How Strimzi Kafka Consumes ~4,280 MiB
Under an identical workload, Strimzi Kafka's memory footprint is composed of:
- JVM Heap Space: Heap pre-allocations (2 GiB initial cap) required to prevent frequent Garbage Collection pauses under high throughput.
- Metaspace & JVM Threads: JVM class metadata, JIT compiler caches, and 1 MiB per-thread stack allocations across dozens of thread pools.
- Off-Heap & Netty Buffers: Direct byte buffers used by network transports and GC card tables.
Cold Start & Failover Recovery
Broker restart and failover agility determine cluster availability during node reboot, autoscaling, and rolling upgrades.
Measurement Methodology
- Cold Start Time: Elapsed wall-clock time from Kubernetes Pod launch until the broker initializes its log directory, establishes KRaft quorum consensus, and accepts its first client connection.
- Failover Recovery Time: Under an active produce workload at replication factor 3, the active partition leader pod is abruptly killed (
SIGKILL). The load driver measures the elapsed duration until the new KRaft leader is elected and successfully acknowledges subsequent produce requests.
How Krabka Achieves 1.2s Cold Start & 1.8s Failover
As a compiled native binary, Krabka bypasses JVM classloading, bytecode verification, and JIT compilation phases. Startup involves only:
- Immediate memory mapping of log segment headers via
krabka-logwithout full-file scans. - Instant KRaft election convergence and metadata state machine snapshot replay via
krabka-raft.
Scenario Matrix Results
The comparative test suite exercises real-world workloads under various partition counts, payload sizes, and failure events:
| Scenario | Payload | Topology | Duration | Krabka Metric | Strimzi Metric | Advantage |
|---|---|---|---|---|---|---|
| small-msg-saturate | 100 B | 6p / RF=1 | 60 s | 182.4 MB/s | 74.8 MB/s | 2.44x |
| fixed-rate-latency | 1 KiB | 6p / RF=1 | 120 s | 1.4 ms (p99) | 8.2 ms (p99) | 82.9% |
| large-msg | 100 KiB | 6p / RF=1 | 60 s | 890.2 MB/s | 512.6 MB/s | 1.74x |
| failover | 1 KiB | 12p / RF=3 | 180 s | 1.8 s (failover) | 12.4 s (failover) | 6.89x |
| high-partition-saturate | 100 B | 100p / RF=3 | 60 s | 245 MB/s | 98.2 MB/s | 2.49x |
Reproducing Benchmarks Locally
Developers can run local microbenchmarks or complete cluster benchmark suites using the open-source recipes:
Microbenchmarks (Criterion)
# In krabka-protocol
cargo bench --bench codec
# In krabka-broker
cargo bench -p krabka-log --bench log OpenMessaging Benchmark (OMB) Cluster Suite
git clone https://github.com/krabka-io/krabka-o11y-demo
cd krabka-o11y-demo/benchmarks
./run-suite.sh --cluster-type gke --target krabka --workload omb-standard