Benchmarking Methodology with kafka-producer-perf-test

Benchmarking Methodology with kafka-producer-perf-test

Anyone can run a load test and get a number. The hard part is getting a number you can trust, explain and repeat. This guide teaches the method: what the tool measures, which settings change the result, how to design fair experiments, and how to turn the numbers into decisions.

Two engineers argue in a meeting. One says, “Our Kafka cluster handles a million messages a second.” The other says, “I measured it last week and got two hundred thousand.” Both are telling the truth. They used different message sizes, different producer settings, different topics and different machines, and they never wrote any of that down.

A benchmark is only useful when it answers a clear question under stated conditions. “How fast is Kafka?” is not a question. “How many 1 KB messages per second can one producer on this machine send to a three-broker cluster with full replication, while keeping the 99th percentile latency under 50 milliseconds?” is a question, and it can be answered.

Kafka ships with a small command-line tool for producing load, called kafka-producer-perf-test. It is simple to run and easy to misuse. This guide explains it from zero, then builds a careful method around it: the settings that matter, how to read the output, how to avoid the classic traps, and how to report results honestly. Every term is explained when it first appears, and each big idea comes with an everyday comparison and worked numbers.

KKafka Producers in Five Minutes

A short refresher on the parts of Kafka that a producer benchmark touches.

Apache Kafka is a system for moving streams of messages between programs. A producer is a program that sends messages. The servers that receive, store and serve them are brokers, and a group of brokers working together is a cluster. Messages are organised into named channels called topics. Each topic is split into partitions, which are ordered lists of messages stored on brokers. Splitting a topic into partitions lets many brokers share the work.

Each partition has one leader broker that handles all reads and writes for it, and copies called replicas on other brokers. Replicas are the safety net: if the leader dies, another replica takes over. When a producer sends a message, it goes to the leader of the right partition, and the leader passes it to the replicas that follow it.

Everyday analogy

Think of a postal sorting centre. Senders (producers) hand parcels to clerks (brokers). Each region of the country (a partition) has one head clerk (the leader) who logs every parcel, and deputies (replicas) who keep copies of the log. A benchmark asks: how many parcels can senders hand over per minute, and how long does each sender wait for a receipt?

Sender

Producer

The program that creates messages and sends them to Kafka.

Receiver

Broker

A Kafka server that stores partitions and answers requests.

Channel

Topic and partition

A topic is the named channel. Its partitions are the parallel lanes inside it.

Backup

Replica

A copy of a partition on another broker, kept for safety.

i
Why this matters for benchmarks

Every one of these parts can be the slowest link. A benchmark result is really the speed of whichever part is the bottleneck under your particular conditions.

WWhy Benchmark at All?

Measuring is how guesses become decisions.

Kafka is used for very different jobs. One team streams tiny click events at huge volume. Another moves large files as messages. A third needs every message safely stored on three machines before it is acknowledged. Each job stresses the system differently, so published numbers from other people’s tests rarely match your case. Benchmarking gives you your own numbers.

Plan

Capacity planning

How many brokers, disks and network links do we need for next year’s traffic?

Tune

Configuration choices

Does a larger batch size or compression help our workload, and by how much?

Compare

Hardware and cloud choices

Is the faster disk type worth its price? Does a different instance type change the ceiling?

Protect

Regression checks

Did the new version, new setting or new network rule make things slower?

Learn

Understanding limits

Where does the system start to struggle, and what fails first?

Prove

Meeting agreed targets

Show that a service level, such as a latency goal, can actually be met.

Everyday analogy

A car maker crash-tests cars before selling them, not after a customer’s accident. Benchmarking is the crash test for your data pipeline, done in a safe place on purpose.

!
A benchmark is a model, not reality

Even a good test is a simplified copy of production. Its value is in comparisons and in finding limits, not in predicting exact production numbers to the last digit.

TThe Tool: What kafka-producer-perf-test Is

A small program that sends a chosen number of messages as fast, or as slowly, as you ask, and reports how it went.

The tool is a command-line program included with Kafka. It creates a producer, generates messages of a size you choose, sends them to a topic, and prints progress and a final summary. Depending on how Kafka was installed it may be a shell script under the name kafka-producer-perf-test, with a “.sh” ending in plain Apache downloads, and it wraps a Java class inside the Kafka tools. It needs no code from you.

What you tell itTypical option namePurpose
Where to sendtopic, and producer properties such as the bootstrap serversChoose the topic and cluster to test
How many messagesnum-recordsTotal messages to send in the run
How big is eachrecord-size, or a payload fileMessage size, or real sample messages
How fastthroughputTarget messages per second, or minus one for no limit
How the producer behavesproducer-props, or a producer config fileAny producer setting: acks, batching, compression, and so on
Extra detailprint-metrics, and transaction optionsPrint the producer’s internal metrics, or test transactions
i
Option names vary slightly by version

Run the tool with its help option on your own Kafka version to see the exact list. Newer versions have added a few options, so treat any list in an article, including this one, as a guide rather than the final word.

What it is not

What it does well

  • Produces steady, repeatable load from one process
  • Lets you set any producer property
  • Reports throughput and latency percentiles
  • Comes with Kafka, so no setup

What it does not do

  • Model your real message shapes and key patterns by default
  • Test consumers, which have their own tool
  • Simulate many different applications at once
  • Check that messages arrive correctly at the other end
Everyday analogy

The tool is like a treadmill for the sending side. It shows how fast the runner can go and how they breathe. It does not tell you how the runner will do on a hilly trail with a backpack, unless you set those conditions up yourself.

AAnatomy of a Run

What happens between pressing Enter and seeing the final line.

flowchart LR
  G["Message generator
size and payload"] --> P["Producer buffers and batches"] P --> N["Network"] N --> L["Partition leader broker"] L --> R["Follower replicas"] R --> L L -->|"acknowledgement"| P P --> M["Latency and throughput recorded"]
Figure 1: the path of each message in a benchmark. Time is measured from the send call to the acknowledgement.
1

Start and connect

The tool builds a producer from your settings and contacts the cluster to learn where partitions live.

2

Generate each message

It makes a message of the chosen size, or picks a sample from your payload file.

3

Hand it to the producer

The producer puts it in a memory buffer, grouped by partition, and waits to form a batch.

4

Send batches

A background thread sends full or old-enough batches to the partition leaders.

5

Receive acknowledgements

When the broker confirms, the tool records how long that message took and counts it as sent.

6

Report progress and finish

Every interval it prints a line for that period, and at the end a summary with totals and percentiles.

Two clocks, two answers

Throughput is how much work is done per second: messages per second, or megabytes per second. Latency is how long one message takes from being sent to being acknowledged. They are related but different. A system can move enormous volume while each message waits a while in a batch. Or it can answer each message very fast while moving less in total. A good benchmark reports both together.

Everyday analogy

A bus carries many people at once but leaves only when full, so each rider may wait. A taxi leaves at once but carries few. Throughput is people moved per hour. Latency is how long one person waits before setting off.

RReading the Output

The tool prints lines while it runs and a summary at the end. Each number has a precise meaning.

FieldMeaningHow to use it
Records sentMessages completed in the run or intervalCheck that it equals the number you asked for
Records per secondMessages acknowledged per secondMain throughput measure for small messages
Megabytes per secondPayload volume per secondMain throughput measure for large messages and for network limits
Average latencyThe mean time from send to acknowledgementRough picture only, since a few slow messages pull it up
Maximum latencyThe slowest single messageReveals pauses, but often one unlucky event
50th percentileHalf of messages were faster than thisThe typical experience
95th, 99th percentile95 or 99 percent were faster than thisThe experience of the slower tail
99.9th percentileAll but the slowest one in a thousand were fasterShows rare but real delays

Why percentiles beat averages

Suppose 990 messages take 5 milliseconds and 10 messages take 500 milliseconds. The average is about 10 milliseconds, which sounds fine. But one message in a hundred waited half a second. A user who happens to hit those slow ones sees a slow service. Percentiles show this. The 99th percentile here is close to 500 milliseconds, which tells the truth the average hides.

5 ms
990 of 1,000 messages
500 ms
10 of 1,000 messages
≈10 ms
average, hiding the slow tail
!
Percentiles are computed from a limited sample

The tool keeps latency measurements in a bounded structure, so very high percentiles are approximate, especially in very long runs. Treat the 99.9th percentile as a useful hint, not a precise figure, and compare it only between runs of similar length.

Everyday analogy

A restaurant says its average wait is ten minutes. But if one table in a hundred waits an hour, those guests never come back. The tail matters as much as the average.

MWhat Exactly Is Being Measured

A latency number is only as meaningful as the stopwatch behind it.

In this tool, latency for each message is generally the time between handing the message to the producer and receiving the broker’s acknowledgement in a callback. That includes time waiting in the producer’s buffer for a batch to fill, the network trip, the broker’s work including replication when the settings require it, and the trip back. It does not include the time for a consumer to read the message. So this is send latency, not end-to-end latency.

Included

Waiting in the batch

Time the message sits until its batch is full or the linger time expires.

Included

Network and broker time

Travel to the leader, writing, and replication if required by the acknowledgement setting.

Not included

Consumer delay

How long until a reader sees the message. That needs an end-to-end test.

Careful

Time blocked before sending

If the producer’s buffer is full, the send call may wait. Depending on the version, that waiting may not appear in the latency numbers, so throughput and latency should be read together.

i
Measure what you need to answer

If the product question is “how soon can a reader see a message”, build an end-to-end test as well. Use the producer tool for the sending side and a matching consumer-side measurement for the reading side.

Everyday analogy

A courier company can time how long from handing over a parcel to getting a receipt. That is not the same as how long until the recipient opens it. Both are valid times, but they answer different questions.

PProducer Settings That Change the Result

Most of the difference between a slow and a fast run lives in a handful of producer settings.

SettingWhat it doesEffect on results
acksHow many brokers must confirm before a send counts as doneZero is fastest and least safe. One waits for the leader. All waits for the in-sync replicas, safest and slower.
batch.sizeMaximum bytes in one batch for one partitionLarger batches raise throughput and can raise latency
linger.msHow long to wait for more messages before sending a batchA few milliseconds often improves throughput a lot
compression.typeWhether and how batches are compressedSaves network and disk, costs processor time, effect depends on the data
buffer.memoryTotal memory for unsent messagesToo small causes the producer to block under load
max.in.flight.requests.per.connectionHow many requests may be outstanding to one brokerHigher can raise throughput, and interacts with ordering and retries
enable.idempotencePrevents duplicates caused by retriesSmall overhead, and it works with certain acks and in-flight limits
request and delivery timeoutsHow long to wait before failing a sendAffects behaviour under trouble, and the tail of latency
Everyday analogy

The batch size is the size of the delivery van, and linger is how long the driver waits for more parcels before leaving. A bigger van and a longer wait moves more parcels per trip but keeps early parcels waiting. Acks is whether the driver must bring back a signed receipt from the recipient’s whole family, or only from the front desk.

Safety settings are performance settings

Choosing acks to be all and enabling idempotence makes messages safer. It also changes speed. A benchmark that uses the fastest, least safe settings will show impressive numbers that production, which needs safety, can never reach. Always test with the durability settings you will actually use.

!
Defaults changed across versions

Some producer defaults, such as acks and idempotence, have changed in recent Kafka releases. Do not assume the default you remember. Print the effective configuration at the start of every benchmark and record it.

BBroker and Topic Settings That Change the Result

The producer is only half the story. The topic you send to shapes the answer.

SettingWhat it controlsEffect on results
Number of partitionsHow many parallel lanes the topic hasMore partitions spread load over more brokers and disks, up to a point
Replication factorHow many copies existMore copies mean more network and disk work per message
min.insync.replicasMinimum in-sync copies needed to accept a write with acks allAffects safety and whether writes stall when a broker is down
Broker threads for network and diskHow much parallel work brokers can doCan shift the bottleneck
Log flush and segment settingsHow data is written and rolled on diskUsually left at defaults, since Kafka leans on the operating system’s cache
Compression at the topic levelWhether brokers recompress dataCan add broker processor cost if it differs from the producer’s choice
1 lane
a single partition can only be led by one broker
Many lanes
let the producer use several brokers at once

A topic with one partition is limited by one leader broker, one disk path and one lane. If your real topic has twelve partitions and three brokers, the test topic should look the same. Otherwise the test measures something you do not run.

i
Create the topic deliberately

Do not let the test create a topic by accident with default partitions. Create it with the partition count and replication factor you want to test, and use a fresh topic name for each test series so old data does not distort results.

Everyday analogy

Testing how fast a supermarket can serve customers with only one checkout open tells you little about a store that opens twelve. Match the number of checkouts to the store you care about.

LThe Latency and Throughput Trade-off

You cannot maximise both at once. Every benchmark chooses a point on a curve.

Batching is the main reason. Waiting to fill a batch moves more data per trip, so throughput rises, but the first message in the batch waits, so latency rises too. Push the load higher and higher and you eventually hit the saturation point, where something in the path is fully busy. Past it, extra load does not raise throughput. It only makes messages queue, and latency climbs sharply.

flowchart LR
  A["Low load
fast, low throughput"] --> B["Moderate load
good balance"] B --> C["Near saturation
throughput flattens, latency rises"] C --> D["Overload
queues build, latency explodes"]
Figure 2: as offered load increases, latency stays low for a while, then rises steeply near the limit.
GoalTypical directionCost
Highest throughputLarger batches, some linger, compressionHigher latency
Lowest latencySmall or no linger, small batchesLower throughput, more requests
Strongest safetyAcks all, idempotence, several replicasBoth slower
Everyday analogy

A motorway carries the most cars per hour at a moderate speed and density. Packed too tightly, traffic slows and the journey time for every driver stretches. The road’s best usable capacity is a little below its absolute maximum.

i
Look for the knee

Plot latency against throughput over several runs. The point where the line bends upward, the knee, is the sensible operating limit. Running production right at the maximum leaves no room for bursts.

TThrottling: Fixed Rate Versus Full Speed

The throughput option decides whether the tool pushes as hard as it can or sends at a steady chosen rate.

Setting the throughput target to minus one removes the limit, and the tool sends as fast as the producer and cluster allow. This finds the maximum throughput. Setting a positive target, for example 50,000 messages per second, makes the tool pace itself to that rate. That measures latency at a given load, which is how real applications behave: they send at the rate their users create, not as fast as possible.

Question

What is the ceiling?

Use no limit. Watch throughput, and expect latency to be poor since the system is pushed to saturation.

Question

How fast is it at our real load?

Use a fixed rate at or near your expected traffic. Latency here reflects normal operation.

Question

Where does it break?

Run a series of fixed rates, stepping up each time, and note where latency turns bad.

Question

Can it handle a burst?

Alternate between low and high rates using separate runs, and watch recovery.

1

Find the ceiling with no limit

Say it reaches about 300,000 messages a second.

2

Step through fixed rates

Run at 25, 50, 75 and 90 percent of that ceiling, each for the same duration.

3

Record latency percentiles at each step

Watch which step first breaks your latency goal.

4

Choose the safe operating point

Pick a rate with headroom below the step that broke the goal.

!
A throttled run reports what was achieved

If you ask for 100,000 a second but the system can only deliver 80,000, the tool reports about 80,000. Always compare the achieved rate with the target. A gap means you have found the ceiling, not a working configuration.

CCoordinated Omission: When Latency Lies

A subtle measurement trap makes systems look faster than they are under stress.

Imagine a shop where customers arrive every minute, but the cashier sometimes freezes for ten minutes. A naive stopwatch measures each customer’s service time from the moment the cashier starts on them. The frozen period barely shows up, because the queue of customers who arrived during the freeze is never timed from their arrival. This hides the real delay users felt. The trap is called coordinated omission: the measurement slows down along with the system, so the worst moments are under-counted.

A load generator that sends the next message only after the previous one is handled, or that pauses when the system is slow, can fall into this. Kafka’s producer is asynchronous and buffers messages, so the situation is less severe than with a simple one-at-a-time client. Still, if the producer’s buffer fills and the send call blocks, time spent blocked may not be counted in the message’s measured latency. The result is that overload can look milder than it is.

Everyday analogy

A doctor measures wait times only from when each patient enters the consulting room, not from when they arrived in the waiting room. The clinic looks efficient, while patients sit for hours outside.

Ways to reduce the risk

  • Use fixed-rate runs so the offered load does not slow down with the system
  • Watch producer metrics such as time blocked and buffer usage
  • Compare achieved throughput with target throughput
  • Repeat with an end-to-end timing that stamps messages at creation

Signs you may be fooled

  • Great latency numbers but throughput far below the target
  • Producer buffer nearly full all the time
  • Long, unexplained pauses in the interval lines
  • Maximum latency much smaller than the visible pauses
i
Rule of thumb

Treat latency numbers from a saturated run as optimistic. Trust latency numbers from a run where the achieved rate equals the target and the buffers stay mostly empty.

RRealistic Payloads and the Compression Trap

What you send changes how fast it goes, especially when compression is on.

The tool can generate messages of a given size from generated data, or read sample messages from a file you provide. Generated data is often simple and repetitive, so it compresses far better than real business data such as JSON with many different values. If you enable compression and test with easy data, the numbers will look wonderful and mean little.

Payload choiceAdvantageRisk
Generated data of a chosen sizeEasy, and exact control over sizeMay compress unrealistically well; ignores real structure
Sample file of real-looking messagesRealistic size mix and compressibilityMust be free of real personal data; the tool picks samples, so make the file representative
Fixed size for every messageClean comparisonsReal traffic usually mixes sizes
Mixed sizes via a fileCloser to realityHarder to reason about single numbers
Size

Message size sets the limit

Small messages are limited by processing per message. Large messages are limited by bytes per second, meaning network and disk.

Content

Compressibility

Repetitive data shrinks a lot. Encrypted or already compressed data shrinks hardly at all.

Keys

Key distribution

Keys decide the partition. A few very common keys create hot partitions that the tool’s default test may never show.

Mix

Size variety

Test small, typical and large sizes, since each stresses a different resource.

Everyday analogy

Testing a luggage conveyor with empty boxes says little about airport day, when suitcases are heavy and oddly shaped. Pack the test bags like real ones.

!
Never put real customer data in a test file

Payload files are copied around, logged and left on disks. Use synthetic data with realistic shape, not real records.

WWarm-up and Steady State

The first seconds of a run are not typical. Measure the part that is.

At the start, several slow things happen at once. The producer must find the cluster, open connections and load metadata. The Java runtime is still optimising its code as it runs. Broker caches are cold. Operating-system memory for the files is not yet filled. Results from this period are often worse than the steady rate that follows. A run that is too short measures mostly the warm-up.

1

Warm-up

Connections open, code is optimised, caches fill. Numbers are unstable.

2

Steady state

Throughput and latency settle. This is the part to measure and report.

3

Cool-down or drift

In long runs, background work such as log rolling, compaction or disk cleaning can cause slow drifts or dips. Note them, since they are part of real life.

Practice

Run a short warm-up first

Send a small batch of messages before the real run, and discard its results.

Practice

Read the interval lines

Look at the per-interval numbers, not just the final summary, to see where the steady part begins.

Practice

Run long enough

Several minutes at least for throughput, and much longer to see disk-related effects.

Practice

Stop before the data volume distorts

Very long runs fill disks and trigger retention deletion, which changes what you measure.

i
Choose the number of messages from the rate

If you expect about 100,000 messages a second and want a five-minute steady window, you need on the order of thirty million messages, not a hundred thousand. A run that finishes in one second measures start-up, not Kafka.

Everyday analogy

An athlete’s first kilometre is slower while muscles warm up. A race time based on the first minute would misjudge them badly.

EThe Environment: Machines, Network and Disks

The same command on two setups gives two answers. Describe the setup fully.

PartWhy it mattersWhat to record
Broker machinesProcessor, memory and disk set the broker ceilingType, cores, memory, disk type and count
DisksEvery message is written to disk, and replicas write tooKind of storage, throughput limits, and whether it is shared
NetworkReplication multiplies traffic between brokersLink speed, distance between machines and zones
Client machineThe load generator can itself be the bottleneckCores, memory, network, and other work running on it
Java runtime and settingsPauses for memory clean-up affect latencyVersion and memory settings on client and brokers
Kafka version and configurationBehaviour and defaults change between releasesExact versions, and all non-default settings
Other tenantsShared machines and shared networks add noiseWhether the cluster and network were otherwise quiet
3×
data written across the cluster with three replicas, per message sent
2×
extra network traffic between brokers for follower copies

A useful sanity check is to do the arithmetic. If one producer sends 200 megabytes a second to a topic with three copies, the cluster receives 200 from the producer and moves 400 more between brokers for the followers, and writes 600 megabytes a second to disks in total. If the network link or disks in your setup cannot carry that, the benchmark will find that limit long before Kafka itself is the bottleneck.

Everyday analogy

A race time depends on the track, weather, shoes and the runner. A record without those details cannot be compared with another record.

!
Do not benchmark on a laptop and quote it as production

Local tests are useful for checking the method and comparing settings, but their absolute numbers say little about a real cluster with separate machines, real disks and a real network.

DDesigning a Fair Experiment

Good benchmarks are small experiments with a question, a hypothesis and controlled conditions.

1

Write the question

For example: does turning on compression raise maximum throughput for our typical JSON messages, and what does it do to the 99th percentile latency?

2

State a guess

Compression should raise throughput because the network is the limit, at a small latency cost. A guess makes surprises visible.

3

Change one thing at a time

Keep every other setting identical between runs. If two things change, you cannot say which caused the effect.

4

Establish a baseline

Run the unchanged configuration first, several times, so you know the normal variation.

5

Repeat each run

Run each variant at least three to five times and look at the spread.

6

Record everything

Write down versions, settings, the exact command, the environment and the time of the run.

7

Decide from the evidence

Ask whether the difference is larger than the run-to-run noise. If not, there is no proven difference.

Everyday analogy

To learn whether a new fertiliser helps, gardeners compare two identical plots in the same weather, changing only the fertiliser. If they also changed the seed and the watering, the result would prove nothing.

i
The noise floor

If three identical runs give 210, 225 and 240 thousand messages a second, differences smaller than about 15 percent between variants are inside the noise. Do not celebrate a 5 percent gain that your own repeated baseline can produce by chance.

MBuilding a Test Matrix

A matrix lists the combinations you will try, so the work stays organised and complete.

RunMessage sizeAcksBatch and lingerCompressionPurpose
A11 KBAllDefaultsNoneBaseline
A21 KBAllLarger batch, 5 ms lingerNoneEffect of batching
A31 KBAllLarger batch, 5 ms lingerFast codecEffect of compression
B1100 bytesAllLarger batch, 5 ms lingerNoneSmall message behaviour
B2100 KBAllLarger batch, 5 ms lingerNoneLarge message behaviour
C11 KBOneLarger batch, 5 ms lingerNoneCost of stronger safety, by comparison with A2

Notice how each row differs from a neighbour in one way, so comparisons stay clean. A full grid of every combination would explode in size. Start with the questions that matter most, and add rows only when a result raises a new question.

Axis 1

Message size

Small, typical, large.

Axis 2

Durability

Acks levels and idempotence.

Axis 3

Batching and compression

Batch size, linger, codec.

Axis 4

Topic shape

Partitions and replication factor.

Axis 5

Load

Unlimited, and several fixed rates.

Axis 6

Parallel producers

One process, then several.

!
Randomise or interleave run order

If you run all baselines in the morning and all variants in the afternoon, time-of-day noise, such as other tenants on a shared cloud, gets mixed into the comparison. Alternate baseline and variant runs to spread that noise evenly.

FFinding the Bottleneck

A result is a symptom. The useful question is which part ran out first.

At the ceiling, one resource is fully busy. Finding it tells you what to change. Improving anything else is wasted effort. The method is to watch all the main resources during the test and see which one is pinned.

flowchart TD
  S["Throughput stops rising"] --> Q1{"Client CPU near 100 percent?"}
  Q1 -- "Yes" --> C1["Client is the limit: add producer processes or machines"]
  Q1 -- "No" --> Q2{"Network link near its limit?"}
  Q2 -- "Yes" --> C2["Network is the limit: compress, or use faster links"]
  Q2 -- "No" --> Q3{"Broker CPU near 100 percent?"}
  Q3 -- "Yes" --> C3["Broker processing is the limit: more brokers or threads"]
  Q3 -- "No" --> Q4{"Disk busy or slow?"}
  Q4 -- "Yes" --> C4["Disk is the limit: faster storage, more disks or brokers"]
  Q4 -- "No" --> C5["Check partitions, settings, replication and pauses"]
Figure 3: a simple decision path from “it stopped getting faster” to the likely bottleneck.
SymptomLikely causeTry
Client processor is pinned, brokers idleLoad generator is too smallRun several tool instances on different machines
Network at its limit on the client or brokerBandwidth ceilingEnable compression, place machines better, or upgrade links
Disk busy and latency rising with loadStorage is the ceilingFaster disks, more brokers, or fewer replicas if safety allows
Everything idle yet throughput is lowToo few partitions, small batches or few in-flight requestsRaise partitions, batch size and linger
Regular latency spikesMemory clean-up pauses, log rolling, or replication hiccupsInspect runtime and broker logs at the time of the spikes
Everyday analogy

A traffic jam on a route could be caused by a narrow bridge, a broken light or a busy junction. Widening the wrong road changes nothing. Find the narrow point first.

WA Worked Example With Illustrative Numbers

Let us walk through a small study from question to conclusion. The numbers are made up to show the method, not to describe any real cluster.

1

The question

Our service sends 1 KB JSON events at up to 60,000 a second. Can a three-broker cluster with three replicas and full acknowledgement handle it with a 99th percentile send latency under 40 milliseconds?

2

The setup

Three brokers with fast disks, a twelve-partition topic with three replicas, acks all, one producer machine.

3

Find the ceiling

Unlimited run, five minutes steady: about 140,000 messages a second, about 140 megabytes a second. The producer machine’s network is at roughly 60 percent, brokers’ processors at 70 percent.

4

Step through fixed rates

Runs at 30,000, 60,000, 90,000 and 120,000 a second, each five minutes.

5

Compare latency

99th percentile is 12, 18, 35 and 140 milliseconds respectively. The knee is between 90,000 and 120,000.

6

Conclude

The target of 60,000 a second is met with about 2 times headroom to the knee, and the latency goal is met. Repeats varied by about 8 percent, so the conclusion is firm.

140k/s
ceiling, illustrative
18 ms
p99 at 60k per second
≈2×
headroom before the knee
Offered rateAchieved ratep50 latencyp99 latencyReading
30,000 per second30,0004 ms12 msComfortable
60,000 per second60,0006 ms18 msTarget load, healthy
90,000 per second90,0009 ms35 msNear the goal limit
120,000 per second118,00025 ms140 msPast the knee, achieved below target
i
Good conclusions include limits

The honest write-up says: for this hardware, this message size and this setting, at this load, the goal is met with headroom. It does not claim the result for other message sizes, other clusters or other settings.

PClassic Pitfalls and How to Avoid Them

Most bad benchmarks fail in the same handful of ways.

Pitfall 1Run too short
What happens

A run of a few seconds measures start-up, connection set-up and code warming, not steady behaviour.

Better

Size the number of messages for several minutes of steady sending, after a discarded warm-up.

Pitfall 2Load generator is the bottleneck
What happens

One small client machine runs out of processor or network before Kafka does, and the team concludes that Kafka is slow.

Better

Watch client resources. If they are busy, add more producer processes on more machines.

Pitfall 3Unsafe settings in the test
What happens

Testing with acks at zero or a single replica gives large numbers that production settings can never match.

Better

Test with the durability settings you will run in production, and show the fast, unsafe result only as a labelled reference.

Pitfall 4Unrealistic data
What happens

Repetitive generated data compresses unrealistically well and hides real network and disk costs.

Better

Use a synthetic sample file with realistic size and variety.

Pitfall 5One run, one number
What happens

A single lucky or unlucky run is treated as the truth.

Better

Repeat runs, report the range, and compare differences against the noise.

Pitfall 6Dirty environment
What happens

Leftover data, other jobs, and unfinished replication from a previous run alter the next one.

Better

Use a fresh topic per series, wait for replicas to be in sync, and keep the cluster otherwise quiet.

i
A pre-flight checklist prevents most of these

Before every series: cluster healthy, replicas in sync, topic created deliberately, client machine idle, settings printed and saved. Ten minutes of checking saves days of arguing about odd results.

IIdempotence and Transactions in the Benchmark

Two correctness features change performance and deserve their own test rows.

An idempotent producer makes retries safe, so a message resent after a timeout is not stored twice. The broker tracks sequence numbers per producer and partition to detect duplicates. This adds a little bookkeeping and puts some limits on other settings, but the cost is often small compared with the safety it gives. In recent Kafka versions it is enabled by default, though you should confirm this for your version.

A transactional producer groups several sends into an all-or-nothing unit, used for exactly-once processing across topics. The tool can be configured with a transactional identifier and a transaction duration, so that it commits after a chosen number of milliseconds. Transactions add extra round trips and coordination, so throughput and latency are affected, and the effect depends strongly on how long each transaction lasts. Short transactions pay a fixed cost often. Long transactions pay it rarely but hold messages back from readers longer.

ModeWhat it protectsBenchmark effect
No idempotenceNothing against duplicate retriesFastest, but duplicates possible on failures
Idempotent producerNo duplicates from retries within one producer sessionSmall overhead
Transactions with short commitsAtomic groups of messagesFrequent commit cost, lower throughput
Transactions with long commitsAtomic groups, fewer commitsBetter throughput, but readers wait longer for committed data
Everyday analogy

Sending each parcel with a tracking number stops the depot from accepting a duplicate. Sending a whole crate that either arrives complete or not at all takes more paperwork per crate, so bigger crates mean less paperwork per parcel but a longer wait before anything in the crate is usable.

!
Readers must be configured to match

A transactional benchmark only tells the full story with consumers that read committed data. Send-side numbers alone will look better than the delay a real reader experiences.

SSecurity Settings and Test Safety

Encryption and login cost performance, and test tools can create risk if handled carelessly.

Cost

Encryption in transit

TLS uses processor time on clients and brokers, and can reduce maximum throughput noticeably, especially for small messages. Test with TLS on if production uses it.

Cost

Authentication and authorisation

Login checks add work when connections open, and permission checks add small costs per request. Test with the same mechanisms production will use.

Risk

Credentials in commands

Passwords typed into command lines are visible in shell history and process lists. Use config files with strict permissions, or a secret store.

Risk

Test traffic in shared clusters

A full-speed run can starve other teams of disk and network. Benchmark in an isolated cluster, or agree windows and limits first.

Risk

Real data in test files

Use synthetic payloads only. Delete test topics and files afterwards.

Risk

Left-over permissions

Remove temporary access rules and test accounts when the study ends.

!
Never run an unlimited benchmark against production

The tool is designed to push as hard as it can. Against a live cluster it can slow or destabilise real services. If production testing is unavoidable, use a strict throttle, a dedicated topic, quotas for the test identity, and a clear stop plan.

Everyday analogy

Testing how many people a fire exit can handle is done with a drill on a day the building is empty, not by filling the lobby during business hours.

MMonitoring While the Test Runs

The tool’s summary tells you what happened. Monitoring tells you why.

WhereWhat to watchWhat it tells you
Client machineProcessor, memory, network use, garbage-collection pausesWhether the load generator is the limit
Producer metrics (via the print-metrics option or a metrics system)Batch size average, records per request, request latency, buffer availability, time blocked, compression ratio, retriesHow batching, compression and the buffer behave
Broker machinesProcessor, disk throughput and wait times, network use, memoryWhich broker resource is saturated
Broker metricsRequest handler idle time, request queue time, produce request time breakdown, under-replicated partitionsWhere time is spent inside the broker, and whether replication keeps up
ReplicationFollower lag and in-sync replica changesWhether followers are falling behind under load
LogsWarnings about slow requests, leader changes, disk problemsExplanations for spikes
Producer

Average batch size

If far below the configured batch size, batches are being sent early. Raising linger may help.

Producer

Buffer available and blocked time

Falling free space or rising blocked time means the producer cannot send fast enough.

Broker

Request handler idle percentage

Low idle means brokers are short of processing threads or processor time.

Broker

Under-replicated partitions

Above zero means followers are behind, which can slow acknowledgement with acks all.

i
Line up the clocks

Record start and end times of each run, and use synchronised clocks on all machines. Then a spike in the interval output can be matched to a broker event in the logs.

!
Metric names differ between versions

Names and availability of client and broker metrics have changed over releases. Confirm them in the documentation for your version before building dashboards or alerts.

SScaling the Load Generator

One tool process can only push so hard. To test bigger clusters you need more load.

A single producer process has limits: its own threads, its network link, and the partitions it happens to be writing to. Real systems have many producer applications at once. To model that, run several copies of the tool in parallel, on separate machines if needed, and add up their results. Give each copy its own share of the target rate.

1

Start with one process

Record its ceiling and how much of the client machine it uses.

2

Add processes gradually

Two, four, eight, each on a separate machine when the client’s own resources become busy.

3

Start them together

Use a scheduler or a script so all processes begin and end at the same moment, otherwise the overlap window is short.

4

Combine results correctly

Add throughputs. Do not average percentiles across processes. Look at each one, or merge the raw latency data if you have it.

Everyday analogy

To test a stadium’s exits you need thousands of people leaving at once, not one very fast walker. And you count the total who left, not the average walking speed.

!
Percentiles cannot be averaged

The 99th percentile of the combined traffic is not the average of each process’s 99th percentile. Averaging hides tails. Compare processes side by side, or collect all latency measurements and compute percentiles once.

BBeyond the Producer: Consumers and End-to-End Tests

The producer test is half of a full picture.

Kafka also ships a consumer performance tool that reads messages and reports how fast it does so. It is used the same way in spirit: choose a topic and a number of messages, and read the throughput. There are also end-to-end approaches, in which messages carry a creation timestamp and the consumer subtracts it from the arrival time, giving the delay from creation to reading. That is what a user of the data really feels.

TestQuestion answeredWho is stressed
Producer performanceHow fast can we write, and how long until acknowledgement?Producer, network, broker write path, replication
Consumer performanceHow fast can we read?Broker read path, network, consumer
End-to-end latencyHow long from creation to being read?Everything, including consumer polling behaviour
Mixed loadHow do reads and writes affect each other?Brokers sharing disks, cache and network
i
Mixed load is more realistic

Real clusters write and read at once. Reads served from memory are cheap, but readers that fall behind cause disk reads that compete with writes. A producer-only test can flatter the cluster.

Everyday analogy

A postal service measures how fast parcels are accepted at the counter, how fast they are delivered from the depot, and how long a parcel takes door to door. Each number is valuable and none replaces the others.

CFrom Results to Capacity Planning

The goal of most benchmarks is a decision: how much do we need?

1

Forecast the load

Estimate peak messages per second and message size, now and for the next year or two. Include growth and seasonal peaks.

2

Convert to bytes

Multiply rate by size, then by the replication factor to get total cluster write load.

3

Use the measured safe rate

Take the rate per broker at the knee, not at the maximum, from your tests.

4

Add headroom

Allow for bursts, broker failure and rebalancing. A cluster that is comfortable with all brokers up must still cope with one down.

5

Plan storage separately

Disk space depends on retention time, not just speed: bytes per second times seconds retained times replication.

50k/s
peak messages, illustrative
1 KB
message size
≈50 MB/s
incoming data
≈150 MB/s
disk writes at three copies

Suppose tests show that each broker safely handles about 60 megabytes a second of incoming data at the knee with three copies. For 50 megabytes a second of peak load, three brokers would run near their safe limit with no failure allowance. Adding a fourth or fifth broker gives room to survive a broker failure and to grow. The exact numbers will differ for you, but the steps are the same.

Everyday analogy

A restaurant does not staff for average Tuesday lunch. It staffs for Saturday night with a cook off sick.

!
Plan for the failure case

When a broker fails, the others take over its partitions and its traffic. Test performance during such an event too, because that is the moment when headroom is used.

RReporting Results Honestly

A result without its conditions cannot be trusted or reproduced.

SectionWhat to include
QuestionWhat the study set out to answer, and the target or goal
EnvironmentKafka version, machine types, disks, network, client details, region or zone layout
ConfigurationTopic settings, producer settings, broker non-default settings, security in use
MethodMessage size and content, run duration, warm-up, number of repeats, load pattern
ResultsThroughput and latency percentiles per run, with the range across repeats
ObservationsWhich resource was the bottleneck, and any events seen during the run
Conclusion and limitsWhat was decided, and what the results do not show

Honest reporting

  • States the conditions along with every number
  • Shows ranges, not a single best run
  • Includes runs that surprised or disappointed
  • Names its limits and unknowns

Misleading reporting

  • Quotes the peak from one lucky run
  • Leaves out safety settings
  • Compares numbers from different setups
  • Claims results for workloads never tested
A number without its conditions is a rumour.
i
Keep the raw output

Save the full tool output, the exact commands and the monitoring graphs for every run. Weeks later, someone will ask how a number was produced, and the raw files are the only reliable answer.

AAutomating and Catching Regressions

A benchmark you run once helps once. A benchmark you can rerun helps every release.

Because the tool is a command-line program, it fits easily into scripts and automated pipelines. A short, standard benchmark can run after each significant change: a new Kafka version, a configuration change, a new instance type, or a new network policy. Comparing each result against a stored baseline reveals slowdowns early, when the cause is still easy to find.

1

Create an isolated, repeatable environment

Build the test cluster from code so every run starts from the same shape.

2

Script the run

Create topic, warm up, run the standard cases, collect output and metrics, then clean up.

3

Store results with metadata

Keep versions, settings and timestamps beside the numbers, in a place where trends can be plotted.

4

Compare against a baseline with tolerance

Flag a change only when it exceeds the known noise, for example ten percent worse than the median of recent runs.

5

Investigate flagged runs

Repeat the run, and if the change is real, bisect between the last good and first bad versions.

Good

Small and fast standard suite

A few well-chosen cases that finish in minutes, run often.

Good

Longer suite on a schedule

A deeper test nightly or weekly, including durability and failure scenarios.

Avoid

Flaky thresholds

Alerts that fire on normal noise teach the team to ignore them.

Avoid

Shared, noisy runners

Cloud machines with unpredictable neighbours make small changes impossible to see.

i
Trends beat single points

A slow drift of two percent per release is invisible in any single comparison but obvious on a chart over a year.

UReal-World Uses

Teams reach for producer benchmarks in a few recurring situations.

Sizing a new cluster

Before buying or provisioning brokers, teams measure per-broker limits with their own message sizes and replication settings, then divide forecast load by the safe per-broker rate.

Choosing between instance or disk types

The same test on two setups shows whether a costlier disk or faster network actually raises the ceiling, or whether the bottleneck is elsewhere.

Validating a version upgrade

Running a standard suite before and after an upgrade shows whether throughput or latency changed, before real traffic is affected.

Tuning a busy producer application

Teams test batch size, linger and compression settings against representative payloads, then apply the winner to the real application.

Checking the cost of security

Measuring the same load with and without encryption gives an evidence-based figure for the extra hardware needed.

Proving a service level

Showing that a latency goal holds at forecast peak load, with headroom, supports launch decisions.

i
About company examples

Many organisations have described their Kafka testing in talks and articles, but practices vary and change. Treat the uses above as common patterns, not as a description of any one company’s method.

BBatching Deep Dive: Size, Linger and Request Shape

Batching is the single biggest lever on producer throughput, so it deserves a closer look.

The producer keeps one open batch per partition it is writing to. A batch is sent when it is full, when its linger time runs out, or when the producer is closing or flushing. Several ready batches for the same broker are grouped into one request. So the size of what actually travels depends on three things: how fast messages arrive, how many partitions they spread over, and the two limits, batch size and linger time.

Fast arrival

Batches fill quickly

When messages arrive faster than the network can send, batches fill to their maximum before the linger time matters. Bigger limits allow bigger batches.

Slow arrival

Linger decides

When messages arrive slowly, batches leave when linger expires, often nearly empty. A small linger adds latency for little gain.

Many partitions

Batches are split thinner

The same message rate spread over many partitions makes each batch smaller, so more requests carry less each.

Keys

Key patterns matter

Random keys spread messages evenly. A few hot keys fill a few batches and leave others idle.

flowchart TD
  M["Message arrives"] --> B{"Open batch for its partition?"}
  B -- "No" --> N["Start new batch and linger timer"]
  B -- "Yes" --> A["Add to batch"]
  N --> A
  A --> F{"Batch full?"}
  F -- "Yes" --> S["Ready to send"]
  F -- "No" --> T{"Linger time reached?"}
  T -- "Yes" --> S
  T -- "No" --> W["Wait for more messages"]
  S --> R["Grouped with other ready batches for the same broker"]
Figure 4: a batch leaves when it is full or when its linger time expires, whichever comes first.

Worked numbers

Suppose messages are 1 KB and the batch limit is 16 KB. A full batch holds about sixteen messages. If 60,000 messages a second are spread over twelve partitions, each partition receives about 5,000 a second, so a batch could fill in about three milliseconds. A linger of five milliseconds is then long enough for nearly full batches. If the same rate spreads over 240 partitions, each gets about 250 a second, a batch would need sixty-four milliseconds to fill, and linger will send small batches long before that. The lesson: the right settings depend on the arrival rate per partition, not just the total.

~16
1 KB messages in a 16 KB batch
~3 ms
to fill at 5,000 per second per partition
~64 ms
to fill at 250 per second per partition
Everyday analogy

A minibus leaves when all seats are taken or after five minutes, whichever comes first. On a busy route it fills instantly. On a quiet route it always leaves after five minutes with a few passengers. Adding more routes for the same passengers makes every bus emptier.

i
Check the average batch size metric

The producer’s average batch size tells you directly whether batching is working. If it is a small fraction of your limit, raise linger a little, or reduce the number of partitions each producer writes to.

CCompression Deep Dive

Compression trades processor time for smaller data. Whether it wins depends on which resource is scarce.

The producer compresses each whole batch before sending, so bigger batches usually compress better, since there are more repeated patterns inside them. Brokers typically store the batch in its compressed form and pass it on to consumers, who decompress it. So a good compression ratio saves network from producer to broker, disk space, replication traffic and network to consumers, at the cost of processor time on the producer and on consumers.

Codec familyCharacterTypical fit
NoneNo processor cost, full sizeData that does not compress, or a network with plenty of room
Fast, light codecsModest shrinking with low processor costMost busy pipelines that want a cheap win
Balanced codecsBetter shrinking, moderate processor costWhen network or disk is the limit and processors have room
Heavy codecsStrong shrinking, high processor costStorage-heavy or bandwidth-starved cases with spare processing
1

Use realistic data

Compression results only mean something on data shaped like yours.

2

Test each codec on the same setup

Hold everything else fixed and compare throughput, latency, processor use and the compression ratio.

3

Watch both ends

Check producer processor use, broker processor use and, if possible, consumer processor use.

4

Decide by the bottleneck

If the network was the limit and processors have room, compression often raises the ceiling. If processors were already the limit, it may lower it.

!
Mismatched codecs can add broker work

If the topic is configured to use a different compression from what the producer used, brokers may need to decompress and recompress data, which costs broker processing. Keep the choices consistent unless you have a reason.

Everyday analogy

Vacuum-packing clothes takes effort at home but lets more fit in the suitcase and on the lorry. It only pays off if the lorry space is the scarce thing and you have the time to pack.

PPartitions and Parallelism

Partitions are how Kafka spreads work, and how a benchmark exposes whether the spread is enough.

Each partition is written by its leader, and a leader handles its partitions using shared broker threads. Too few partitions and some brokers or disks sit idle. Too many and each carries less traffic, batches become thin, and the cluster spends more effort on bookkeeping and replication between partitions. There is a sweet spot, and a benchmark is the way to find it.

Partition countLikely effect on throughputLikely effect on other things
Fewer than brokersSome brokers not usedUneven load, lower ceiling
A few times the number of brokersGood spread, thick batchesOften a good balance
Very manyThin batches, more requestsMore memory, more metadata, slower recovery after failures

Leader balance

Check that leaders are spread evenly. If one broker leads most partitions, it carries most of the write load, and the benchmark finds that one broker’s limit instead of the cluster’s. Look at the distribution before you start, and rebalance leaders if needed.

Check

Leaders per broker

Should be roughly equal across brokers.

Check

Partitions per disk

Where brokers have several disks, ensure data is spread evenly across them.

Check

Key distribution

If keys are skewed, some partitions get most of the traffic.

Check

Rack or zone spread

Replicas placed across zones add network hops that affect latency.

Everyday analogy

A supermarket with twelve checkouts but one busy cashier’s queue is no faster than a shop with one till. Spreading customers evenly is the whole point of opening more checkouts.

i
Sweep the partition count

Run the same test at several partition counts, such as one, three, twelve and thirty-six, and plot the ceiling. The curve rises, flattens and may fall. Pick the point at the start of the flat part.

FFailure and Recovery Testing

Performance on a good day is only half of the story. What happens when something breaks?

Real clusters lose brokers, suffer slow disks and drop network packets. A benchmark that only runs in perfect health will not reveal how your setup behaves in trouble. Combine a steady, throttled load with a planned failure and watch what the producer sees.

1

Start a steady fixed-rate load

Choose a realistic rate with comfortable headroom, and let it reach steady state.

2

Stop one broker cleanly

Leadership for its partitions moves to other brokers. Watch the latency spike and how long it lasts.

3

Observe the producer

Look for retries, timeouts, errors and any message loss or duplicates, according to your safety settings.

4

Restart the broker

Watch it catch up. Catch-up traffic competes with normal load and can slow producers.

5

Repeat with an abrupt failure

Killing a broker without a clean stop is harsher, and detection takes longer.

ScenarioWhat you learn
Clean broker shutdownBest-case failover time and latency blip
Abrupt broker lossDetection delay and worst-case producer errors
Broker restart under loadRecovery traffic effects
Slow disk or network on one brokerWhether one weak broker drags down acks all writes
Fewer in-sync replicas than requiredWhether producers fail fast or wait, given your minimum in-sync setting
!
Do this only in a test cluster

Failure tests intentionally break things. Run them in an isolated environment with agreed access, and never as a surprise on a shared or production system.

Everyday analogy

A fire drill tests more than how fast people walk on a normal day. It reveals whether doors open, whether signs are clear and how long it takes when a corridor is blocked.

DDesign Patterns and Anti-Patterns

A few working habits recur in good benchmarks, and a few recur in bad ones.

Patterns that work

Pattern

Question first

Every study starts with a written question and a success criterion.

Pattern

One variable at a time

Change a single thing between paired runs.

Pattern

Baseline and repeats

Run the baseline several times to learn the noise.

Pattern

Step-load ladder

Increase fixed rates in steps and find the knee.

Pattern

Monitor everything

Client, network, brokers, disks and logs, all recorded with run times.

Pattern

Infrastructure as code

The test cluster is built from scripts so it is identical each time.

Anti-patterns to avoid

AP-1Anti-pattern
Chasing the biggest number

Tuning until a headline throughput appears, using settings no production system could use.

Better

Target a stated goal under production-like conditions.

AP-2Anti-pattern
Changing many settings at once

Adjusting batch size, compression, acks and partitions together, then not knowing what helped.

Better

Change one setting per comparison.

AP-3Anti-pattern
Benchmarking a live shared cluster

Running full-speed tests where real services depend on the same brokers.

Better

Use an isolated cluster, or strict limits and agreed windows.

AP-4Anti-pattern
Trusting the average

Deciding on average latency while the tail is poor.

Better

Decide on percentiles that match user impact.

AP-5Anti-pattern
Undocumented runs

Numbers with no record of settings or environment.

Better

Save configuration, commands and raw output with every result.

BBest Practices and Common Mistakes

A checklist to keep by your side.

Best practices

  • Write the question and the target before running anything
  • Use production-like message sizes, content and durability settings
  • Create the topic deliberately with the intended partitions and replicas
  • Warm up, then measure a long steady window
  • Use fixed-rate runs to measure latency, and unlimited runs to find ceilings
  • Repeat runs and compare differences with the noise
  • Watch client, network, broker and disk resources together
  • Look at percentiles, not only averages
  • Record configuration and keep raw outputs
  • Report results with their conditions and limits

Common mistakes

  • Runs so short they measure start-up
  • A weak client machine that becomes the bottleneck
  • Fast but unsafe settings that production will not use
  • Compressible fake data that flatters compression
  • Comparing runs from different environments
  • Reading latency from a saturated run as if it were normal
  • Averaging percentiles across processes
  • Leaving old data and unfinished replication in place
  • Testing on a shared production cluster
  • Quoting one best run as the result
i
A five-line sanity check for any claim

What was the question? What were the conditions? How many repeats? Which resource was the bottleneck? What is the noise? If a number arrives without answers to these, do not build a decision on it.

MMyths and Misunderstandings

Some beliefs sound sensible and lead teams astray.

MythReality
“The tool tells us how fast Kafka is.”It tells you how fast this producer setup ran against this cluster under these conditions.
“Bigger batches are always better.”They raise throughput up to a point and add latency. Very thin traffic per partition cannot fill them.
“More partitions always means more speed.”Beyond a point, batches thin out and overhead grows.
“Compression always helps.”It helps when network or disk is scarce and processors have room, and on data that compresses.
“Average latency shows user experience.”Users feel the tail, which percentiles reveal.
“A laptop test predicts production.”It checks the method, not real capacity.
“If throughput hits the target, we are fine.”Latency, headroom, failure behaviour and safety settings matter too.
“The producer test covers the whole pipeline.”It covers only the send side. Consumers and end-to-end delay need their own tests.
“Run it once, it is deterministic.”Real systems vary. Repeats reveal how much.
The tool gives you measurements. The method turns them into knowledge.

CCloud and Container Cautions

Modern platforms add layers that can silently change your results.

Burst credits

Temporary performance

Some cloud machines and disks give fast performance for a while, then throttle. A short test looks great, a long one collapses. Run long enough to see the sustained rate.

Noisy neighbours

Shared hardware

Other customers’ load on the same host can change your numbers from hour to hour. Repeat and interleave runs.

Limits

Container resource limits

Processor and memory limits apply even when the host has more. A limit on the load generator can quietly cap the test.

Network

Overlay networks and zones

Extra network layers and cross-zone traffic add delay and costs. Place clients and brokers as production will be placed.

Storage

Network-attached disks

These have provisioned speed limits that differ from local disks. Know your limits and test near them.

Cost

Data transfer charges

Large tests can create real bills for traffic between zones. Estimate before running.

SymptomPossible platform cause
Fast at first, then slowerBurst allowance ended on disk or network
Results differ by time of dayShared hardware or shared network load
Client stuck at a rate below expectationsProcessor or network limit on the container
Latency higher than same-machine testsCross-zone or overlay network hops
Everyday analogy

A sprinter who can run fast for ten seconds is not a marathon runner. Cloud burst limits are the same: the opening seconds do not show what can be sustained.

PPutting It All Together: A Study Plan

A complete plan from start to finish, in the order to do things.

1

Define the question and the goal

Peak rate, message size, latency target, durability needs, and the decision the study will support.

2

Prepare the environment

Isolated cluster of the intended shape, healthy and quiet. A client machine large enough not to be the limit.

3

Prepare the data

Synthetic payload file with realistic sizes and compressibility.

4

Create topics deliberately

Correct partitions, replication and minimum in-sync setting. Check leader balance.

5

Baseline runs

Production settings, several repeats, to learn the noise and the ceiling.

6

Step-load ladder

Fixed rates in steps. Record percentiles and find the knee.

7

One-variable comparisons

Batching, compression, partitions, security, transactions, each against the baseline.

8

Failure tests

Broker stop, abrupt loss and restart under steady load.

9

Consumer and end-to-end checks

Confirm the whole pipeline meets the goal.

10

Report and decide

Write up conditions, results, bottlenecks and limits, then make the sizing or tuning decision, and save the scripts for reruns.

1
question per study
3–5
repeats per variant
Minutes
of steady state per run
1
change at a time
i
Start small

Even a two-hour study with a baseline, a step ladder and one comparison gives more trustworthy knowledge than dozens of casual runs. Grow the plan as questions arise.

SSimple Statistics for Comparing Runs

You do not need advanced mathematics to avoid fooling yourself. A few simple habits are enough.

Suppose the baseline gives 200, 210 and 205 thousand messages a second, and a variant gives 215, 220 and 212. The variant’s average is about 216 and the baseline’s about 205. Is the variant better? The spread inside each group is about 10 thousand. The gap between groups is about 11 thousand. That is close to the noise, so the honest answer is “probably slightly better, but run more repeats”. If the variant had given 250, 255 and 248, the gap would be far larger than the spread and you could be confident.

HabitHow to do itWhy
Use the median for a typical valueSort the repeats and take the middle oneOne odd run does not distort it
Report the rangeShow the lowest and highest repeatShows how much the result wobbles
Compare the gap to the spreadIs the difference bigger than the range within a group?Separates real effects from noise
Look at latency percentiles per runDo not average percentiles from different runs blindlyTails hide in averages
Add repeats when unsureRun a few more of each variantMore data narrows doubt
Check for trends across the order of runsPlot results by the time they ranReveals warming, throttling or time-of-day effects
≈205k
baseline median, illustrative
≈215k
variant median, illustrative
≈10k
spread inside each group
Everyday analogy

If two runners’ finishing times differ by one second but each runner’s own times vary by three seconds from race to race, you cannot say one is faster. You need more races.

i
Write the decision rule before the test

Decide in advance: “we adopt the change if the median throughput rises by at least 10 percent and the 99th percentile does not worsen.” Setting the rule first stops you from reading the results in whichever way you prefer.

BThe Producer Buffer and Back-Pressure

When the producer produces faster than the cluster accepts, memory fills, and behaviour changes.

The producer keeps unsent messages in a pool of memory. Messages enter the pool when the application sends them and leave when the broker acknowledges them. If messages arrive faster than they leave, the pool fills. Then the producer applies back-pressure: the send call waits for space, up to a configured maximum blocking time, and then fails. This is a healthy safety valve, but it changes what a benchmark measures.

flowchart LR
  A["Application sends"] --> P["Buffer pool"]
  P --> S["Sender thread"]
  S --> B["Broker"]
  B -->|"acknowledgement frees space"| P
  P -->|"pool full"| W["Send call waits, then may fail"]
Figure 5: the buffer fills when sending outpaces acknowledgements, and then the application must wait.
1

Load below capacity

The buffer stays mostly empty. Messages leave almost as soon as they arrive.

2

Load at capacity

The buffer holds a modest backlog. Latency rises a little.

3

Load above capacity

The buffer fills. The application waits. Throughput equals capacity, and measured latency depends on how the waiting is counted.

Sign

Buffer space near zero

The cluster or network cannot keep up with the producer.

Sign

Rising blocked time

The application is waiting on the producer, so you are past the ceiling.

Fix

Bigger buffer

Absorbs short bursts, but does not raise the sustained ceiling.

Fix

More capacity

Raise the real ceiling with brokers, partitions or network, then test again.

Everyday analogy

A bath fills if the tap runs faster than the drain. A bigger bath delays the overflow, but only a wider drain solves it.

!
A larger buffer can flatter a short test

A big buffer absorbs the whole run without ever blocking, so a short test may look perfect. A longer run then reveals the true limit. Another reason to run for minutes, not seconds.

RRetries, Timeouts and Errors in Results

A run that completes is not always a run that succeeded. Look for hidden trouble.

When a send fails for a temporary reason, such as a leader change, the producer retries automatically within limits set by its timeouts. Retries hide short problems from the application, but they add delay, and they consume capacity. A benchmark that shows good throughput while retries quietly climb is telling you the system is under strain.

What to checkWhere to see itWhat it suggests
Retry rateProducer metricsInstability, leader changes, or overloaded brokers
Error rateTool output and producer metricsSends that gave up. Any errors mean the run is not clean.
TimeoutsProducer logsRequests waiting too long for brokers or replicas
Records sent versus requestedTool summaryConfirms every message was acknowledged
Under-replicated partitionsBroker metricsFollowers falling behind, which slows acks all

A clean run

  • All requested records acknowledged
  • Retries near zero
  • No errors or timeouts
  • Replicas stay in sync

A suspect run

  • Some records failed or timed out
  • Retries rising during the run
  • Replicas dropping out of sync
  • Large pauses in the interval lines
Everyday analogy

A courier who reports “all parcels delivered” but had to re-attempt half of them has not had a good day. The retries cost time and effort that the final count does not show.

i
Discard unclean runs from comparisons

If a run had errors or heavy retries, investigate before using its numbers. Mixing clean and troubled runs makes comparisons meaningless.

IReading the Interval Lines Like a Chart

The lines printed during the run are a time series. Reading them in order tells a story the final summary cannot.

While it runs, the tool prints a line for each reporting interval, giving the count, rate and latency for just that stretch. If you copy those lines into a spreadsheet and plot rate and latency against time, patterns appear at once.

Shape over timeLikely meaningAction
Low at first, then steadyNormal warm-upExclude the early part from results
Steady, then a sudden dropBurst allowance ended, a broker issue, or memory clean-up stormsCheck platform limits and logs at that time
Regular sawtoothPeriodic background work such as log rolling, or batching cyclesFind the period and match it to a broker setting
Slow downward driftDisk filling, caches turning over, or growing filesRun longer and watch disk and memory
Rare huge spikesLeader elections, pauses, or network hiccupsCorrelate with broker logs
Tip

Use a modest interval

Around one second is common. Much longer hides short spikes, much shorter produces noisy lines.

Tip

Save the raw lines

Keep them with the run. The summary alone cannot be re-analysed.

Tip

Overlay with monitoring graphs

Put the tool’s rate line and the broker’s disk and processor graphs on the same time axis.

Tip

Mark events

Note the exact time of any change or failure you introduce, so it can be found on the chart.

Everyday analogy

A doctor reading a single blood pressure number learns less than one reading a chart of the whole day. The pattern over time shows what a snapshot hides.

TA Tuning Playbook: Symptom, Cause, Try

When a benchmark disappoints, work through these ideas in order of cost and likelihood.

1

Confirm the test is fair

Client not saturated, topic shape right, data realistic, run long enough. Many “slow Kafka” reports end here.

2

Improve batching

Raise linger a few milliseconds and increase the batch size, and check that average batch size now grows.

3

Try compression

If the network is the limit and processors have room, test a light codec on realistic data.

4

Adjust partitions

Ensure enough partitions to use every broker and disk, but not so many that batches thin out.

5

Check in-flight requests and buffer

Allow enough outstanding requests and buffer memory so the producer never starves the network.

6

Look at the broker side

Threads, disks, network, replication lag, and leader balance.

7

Scale out

If everything is tuned and one resource is still full, add capacity: brokers, faster disks or links.

SymptomFirst thing to tryWatch afterwards
Low throughput, everything idleMore linger and larger batches; more partitionsAverage batch size, records per request
Good throughput, poor tail latencyReduce linger, check for pauses, check replication lag99th percentile, garbage-collection and broker logs
Network saturatedCompressionCompression ratio, processor use
Client processor saturatedMore producer processes or machines, lighter compressionClient processor and per-process rates
Disk saturated on brokersMore brokers or disks, faster storageDisk wait, request time breakdown
Latency spikes during broker eventsReview timeouts, in-sync settings and failure handlingRetry counts and leader change logs
i
Cheap changes first

Settings that cost nothing and can be undone, such as linger and batch size, come before buying hardware. And always re-run the baseline after each change, so you know that the change did what you think.

Everyday analogy

Before rebuilding a slow kitchen, check that the cooks have the ingredients, the orders are batched sensibly, and nobody is standing in the doorway. Only then, buy a bigger oven.

OOrganising the Work: Folders, Names and Notes

Good records turn a pile of runs into evidence anyone can check.

flowchart TD
  S["Study folder"] --> P["Plan: question, goal, decision rule"]
  S --> E["Environment notes: versions, machines, network"]
  S --> R["Runs"]
  R --> R1["Run folder: command, settings, raw output"]
  R --> R2["Run folder: monitoring graphs and logs"]
  S --> A["Analysis: tables, charts, conclusions"]
Figure 6: one study folder, with the plan, the environment, each run and the analysis kept together.
Names

Meaningful run names

Include date, case code and variant, such as a matrix row label, so a folder explains itself.

Notes

A short log per run

Anything unusual: a restart, a noisy neighbour, a mistake in the command.

Versions

Record software versions

Kafka, Java, operating system and any tooling, for both clients and brokers.

Sharing

Write for a stranger

Someone who was not there should be able to repeat the run from your notes.

i
Repeatability is the real test

If a colleague can follow your folder and get similar numbers, your benchmark is a piece of knowledge. If not, it is a story.

Everyday analogy

A recipe that says “bake until done” cannot be repeated. One with temperature, time and quantities can be cooked by anyone, and criticised fairly if it fails.

QQuick Reference: Starting Points by Goal

Where to begin your first test runs for common goals. These are starting hypotheses to test, never final answers.

GoalStarting hypothesisWhat to confirm by measuring
Maximum throughput with safetyAcks all, idempotence on, moderate batch size, a few milliseconds of linger, light compression on realistic dataAverage batch size grows, network or disk becomes the bottleneck, tail latency stays acceptable
Lowest send latencyAcks all or one according to safety needs, minimal linger, modest batch size, no heavy compressionThe 99th percentile at your real rate, and that throughput still meets the target
Many small messagesEnough linger to form useful batches, compression to cut request overheadRecords per request and broker processor use
Few large messagesBatch size large enough to hold them, careful with buffer memory and message size limitsMegabytes per second against network and disk limits
Bursty trafficGenerous buffer, fixed-rate tests at burst peaksBuffer availability during bursts and recovery afterwards
Strict ordering with retriesIdempotence on, limited in-flight requests as allowed by your versionOrdering preserved and throughput cost measured
Rule

Hypothesis, not recipe

Every row is a guess to check with your own data and hardware.

Rule

Confirm with metrics

Each hypothesis names a metric that shows whether it worked.

Rule

Revisit after upgrades

Defaults and internals change, so old findings may expire.

Rule

Keep the safe baseline

Always compare any faster setting against a setting you would actually be allowed to run.

Everyday analogy

A cookbook suggests a starting temperature, and a good cook adjusts by looking in the oven. These starting points are the cookbook. Your measurements are looking in the oven.

i
Write down what surprised you

The most valuable findings are the times when a hypothesis was wrong. Record them, since they show where your mental model of the system needs to change.

GGlossary of Terms in Plain Words

A quick reference for the terms used in this guide.

TermPlain meaning
ProducerA program that sends messages to Kafka
BrokerA Kafka server that stores and serves messages
Topic and partitionA named channel, and its parallel ordered lanes
Leader and replicaThe broker handling a partition, and its backup copies
ThroughputWork done per second, in messages or megabytes
LatencyTime one message takes from send to acknowledgement
PercentileThe value below which a stated share of measurements fall
Tail latencyThe slowest few percent of messages
AcksHow many brokers must confirm a send before it counts
BatchA group of messages sent together for one partition
LingerHow long the producer waits to fill a batch
Idempotent producerA producer whose retries never create duplicates
TransactionA group of sends that succeed or fail together
SaturationThe point where a resource is fully busy
KneeThe load level where latency begins to rise steeply
Warm-upThe unstable early period before performance settles
Steady stateThe stable period that should be measured
Coordinated omissionA measurement flaw where slowdowns hide their own delay
BaselineThe unchanged configuration used for comparison
NoiseNatural run-to-run variation
HeadroomSpare capacity above expected load

FFrequently Asked Questions

Q1

How many messages should I send in a run?

Enough to last several minutes at steady state. Multiply your expected rate by the seconds you want, for example one hundred thousand a second for five minutes is thirty million messages.

Q2

Should I test with an unlimited or a fixed rate?

Both. Unlimited finds the ceiling. Fixed rates show latency at realistic load and reveal the knee.

Q3

Why is my throughput far below what others report?

Others probably used different message sizes, safety settings, hardware or partitions. Compare conditions, and check whether your client machine, network or a single busy broker is the limit.

Q4

Is the latency the tool reports the end-to-end latency?

No. It is the send latency from handing over a message to receiving the acknowledgement. Consumer delay needs a separate end-to-end measurement.

Q5

Which acks setting should I benchmark?

The one you will use in production. If you need durability, that means acknowledgement from all in-sync replicas. Show weaker settings only as labelled references.

Q6

How do I know if the load generator is the limit?

Watch its processor and network. If it is nearly full while brokers have room, run more tool processes, on more machines if needed.

Q7

Can I trust the 99.9th percentile?

Use it as a hint. It is based on far fewer slow samples and is approximate. Compare it only between runs of similar length and repeat to see its variation.

Q8

How many repeats do I need?

Three to five per variant is a good start. More if the results vary widely.

Q9

Do I need a payload file?

It is strongly advised when using compression or when message contents matter. Generated data can be unrealistically easy to compress. Always use synthetic content, not real customer data.

Q10

Can I run the tool against production?

Avoid it. If you must, use a dedicated topic, a strict throttle, quotas and a clear stop plan, since an unlimited run can harm real services.

Q11

Why do results change from day to day on the cloud?

Shared hardware, burst allowances and other tenants change available capacity. Interleave runs, repeat, and use long enough tests to see sustained speed.

Q12

Do the option names differ between Kafka versions?

Some options have been added or changed over time, and defaults have shifted too. Check the help output and documentation for your version, and record the exact command you ran.

SSummary and Key Takeaways

The whole method in a few lines.

The kafka-producer-perf-test tool sends messages of a chosen size, at a chosen rate, with chosen producer settings, and reports throughput and latency percentiles. On its own it produces numbers. A method turns those numbers into knowledge: ask a clear question, mimic production in message shape, durability and topic layout, warm up and measure steady state, change one variable at a time, repeat to learn the noise, watch every resource to find the bottleneck, and report results with their conditions. Use unlimited runs to find ceilings, and fixed-rate ladders to find the knee where latency turns bad. Remember that send latency is not end-to-end latency, that saturated runs flatter latency, and that safety settings are performance settings. Done this way, a benchmark supports real decisions about sizing, tuning and upgrades.

Key Takeaways

  • A benchmark answers a specific question under stated conditions; a number without conditions is a rumour.
  • Test with production-like message sizes, content, topic layout and durability settings.
  • Warm up, then measure several minutes of steady state, and repeat each run to learn the noise.
  • Use unlimited runs to find the ceiling and fixed-rate steps to find the knee; judge latency by percentiles, not averages.
  • Change one variable at a time, and watch client, network, broker and disk resources to find the true bottleneck.
  • The tool measures send latency only; test consumers and end-to-end delay separately, and beware coordinated omission.
  • Plan capacity from the safe rate with headroom for failures, and report results with their environment and limits.