Skip to content

AxonOps — AI-Native Control Plane for Open Source Data Platforms

Kafka Performance Internals

Deep dive into Kafka's performance architecture and optimization techniques.


Layers of the Kafka performance stackLayers of the Kafka performance stackKafka Performance StackBatchingCompressionSequential I/OZero-CopyPage CacheEfficient SerializationEach layer multipliesperformance benefitsreducesmessagessmallerwritesoptimaldisk usememoryefficiencyminimalcopies

For complete log segment structure, indexes, and retention policies, see Storage Engine.

Kafka appends all writes to the end of log segments, achieving sequential disk access.

Random database writes compared with Kafka sequential appendRandom database writes compared with Kafka sequential appendTraditional DatabaseRandom WritesKafkaSequential AppendPage 1Page 5Page 2Page 8Offset 0Offset 1Offset 2Offset 3Seeks between pages~100 IOPS on HDDSingle sequential stream~100+ MB/s on HDD
Access PatternHDD Performance (illustrative)SSD Performance (illustrative)
Random 4KB~100 IOPS~100K IOPS
Sequential~100 MB/s~500 MB/s
Kafka advantageOrder-of-magnitude on HDDSmaller delta on SSD

Traditional read and send path with four data copiesTraditional read and send path with four data copiesApplication Read/SendDiskKernelBufferUserBufferSocketBufferNIC4 data copies2 context switchesCPU overhead1. DMA read2. CPU copy3. CPU copy4. DMA send
Zero-copy send path using sendfile()Zero-copy send path using sendfile()Kafka sendfile()DiskPageCacheNIC0 CPU copiesDirect kernel transferMinimal CPU usage1. DMA read2. DMA send
// Kafka uses FileChannel.transferTo()
// which maps to sendfile() system call
fileChannel.transferTo(position, count, socketChannel);
ConditionZero-Copy Available
PlaintextYes
TLS/SSL enabledNo (encryption requires user-space)
CompressionYes (independent of compression)

TLS Impact

Enabling TLS disables zero-copy; throughput impact depends on CPU and workload.


Producer record accumulator batching per topic partitionProducer record accumulator batching per topic partitionProducerRecordAccumulatorTopic-PartitionBatchesSenderP0 BatchP1 BatchP2 BatchBrokerbatch readybatch readysingle requestmultiple batches
ParameterDefaultEffect
batch.size16384Maximum bytes per batch
linger.ms0Time to wait for more records
buffer.memory33554432Total memory for batching
Without batching (1000 messages):
1000 network round-trips
1000 small disk writes
High overhead per message
With batching (1000 messages in 10 batches):
10 network round-trips
10 larger disk writes
Amortized overhead
# Minimum data to fetch
fetch.min.bytes=1
# Maximum time to wait
fetch.max.wait.ms=500
# Maximum data per request
fetch.max.bytes=52428800

AlgorithmIndicative Ratio (varies by data)CPU UsageSpeed
none1.0xNoneFastest
gzip~5-8xHighSlow
snappy~2-3xLowFast
lz4~3-4xLowFastest
zstd~4-6xMediumFast
Compression flow from producer through broker to consumerCompression flow from producer through broker to consumerProducerBrokerConsumerBatch(uncompressed)CompressedBatchStored(compressed)DecompressedBatchBroker stores compressed dataRecompresses only if configuredcompressstore as-isdecompress
# Producer compression
compression.type=lz4
# Topic-level compression (broker will recompress if different)
compression.type=producer # Keep producer compression
compression.type=gzip # Force specific compression
Use CaseRecommended
High throughput, low latencylz4
Balancedzstd
Maximum compressiongzip
Minimal CPUsnappy
Already compressed datanone

Pipelined in-flight producer requestsProducerBrokerProducerProducerBrokerBrokerRequest 1Request 2Request 3Response 1Response 2Response 3Multiple requests in flightwithout waiting for responses
# Maximum in-flight requests
max.in.flight.requests.per.connection=5
SettingOrderingThroughput
max.in.flight=1GuaranteedLower
max.in.flight=5May reorder on retryHigher
max.in.flight=5 + idempotentGuaranteedHigher

Broker network and I/O thread modelBroker network and I/O thread modelBroker Thread ModelNetwork Threads(num.network.threads)I/O Threads(num.io.threads)Request QueueResponse QueueAcceptReadWriteIO-1IO-2IO-Nenqueueprocessenqueuesend
ParameterDefaultRecommendation
num.network.threads3CPU cores / 4
num.io.threads8CPU cores
num.replica.fetchers12-4 for high partition counts
num.recovery.threads.per.data.dir12-4 for faster recovery

Read latency by page cache stateRead latency by page cache stateRead ScenariosHot Read(cache hit)Warm Read(partial hit)Cold Read(cache miss)~sub-ms~1-5 ms~10+ msRecent data served from memoryConsumer lag = more cache misses
Total RAM: 64 GB
JVM Heap: 6 GB (enough for metadata)
OS/System: 2 GB
Page Cache: 56 GB (for log data)
If hourly throughput = 50 GB
Page cache covers ~1 hour of data

Terminal window
# Throughput test
kafka-producer-perf-test.sh \
--topic test-topic \
--num-records 10000000 \
--record-size 1024 \
--throughput -1 \
--producer-props \
bootstrap.servers=kafka:9092 \
batch.size=65536 \
linger.ms=10 \
compression.type=lz4
Terminal window
# Throughput test
kafka-consumer-perf-test.sh \
--bootstrap-server kafka:9092 \
--topic test-topic \
--messages 10000000 \
--threads 4
Terminal window
kafka-run-class.sh kafka.tools.EndToEndLatency \
kafka:9092 \
test-topic \
10000 \
all \
1024

MetricExample Range
RequestsPerSecDepends on workload
TotalTimeMs (P99)< 100 ms
RequestQueueTimeMs< 10 ms
LocalTimeMs< 50 ms
RemoteTimeMs< 50 ms
ThrottleTimeMs0
SymptomLikely Bottleneck
High RequestQueueTimeMsNetwork threads saturated
High LocalTimeMsDisk I/O or I/O threads saturated
High RemoteTimeMsReplication lag
High ResponseQueueTimeMsNetwork threads saturated