Producer/Broker Throughput Ceiling Analysis in Kafka
Why Kafka cannot go faster than a certain speed, and how to find out exactly which part is holding it back. Explained from zero, with everyday pictures, clear diagrams, worked arithmetic, and a step-by-step way to measure and raise your own ceiling.
Picture a highway with several sections: a wide entrance ramp, a six-lane main road, a narrow bridge, and an exit road. Cars can only travel as fast as the narrowest section allows. Add ten more lanes to the main road, and traffic still crawls if the bridge has two lanes. The number of cars per hour that the whole highway can carry is decided by its narrowest part, not by its widest.
Apache Kafka works the same way. A message travels from an application, through a network, into a server, onto a disk, across the network again to copies on other servers, and finally out to readers. Every step has a maximum speed. The overall speed of the system, called its throughput, can never go above the slowest step. That upper limit is the throughput ceiling.
Many teams meet this ceiling in an unpleasant way: at three in the morning, during a traffic spike, when producers begin to time out. A ceiling analysis is the calm, planned way to meet it earlier. You learn what your ceiling is, which part sets it, how much room you have left, and what to change to lift it. This guide teaches that from the very beginning, with no earlier knowledge assumed.
Why Throughput Ceilings Matter
Speed problems rarely come from where people first look.
When Kafka feels slow, most people say “we need more brokers” or “let us tune something.” Sometimes that is right. Often it is wrong, because the real limit sits somewhere else: a producer that sends tiny messages one by one, a network card that is already full, a disk that cannot write fast enough, or a single thread inside a broker that is always busy. Adding brokers does nothing for a problem that lives inside the producer.
Know your headroom
If the ceiling is 800 megabytes per second and you use 600, you have room for about a third more growth. Without the ceiling, you are guessing.
Buy the right thing
Faster disks, bigger network cards, or more machines cost different amounts. Pay only for the one that lifts your limit.
Survive failures
When one broker fails, the others must carry its work. A cluster already at its ceiling has no room for that.
Fewer surprises
Traffic spikes, sales events, and backfills are predictable when you know how much the system can take.
A restaurant owner who knows the kitchen can cook 120 plates an hour will not accept a booking for 300 guests at once. Knowing the ceiling lets the owner say yes, no, or “come at staggered times” before customers are angry.
A ceiling is not one number for all of Kafka. It is a number for your particular setup: your message sizes, your number of copies, your machines, your settings. That is why it must be measured, not copied from a blog post.
Kafka Basics You Need First
Just enough vocabulary to follow everything else.
Apache Kafka is a system for moving streams of messages between programs. One program writes messages, others read them, and Kafka stores them safely in between. Here are the words we need.
| Word | Plain meaning | Picture |
|---|---|---|
| Message (record) | One piece of data, such as “order 1234 was placed” | A single letter |
| Producer | A program that sends messages to Kafka | The person posting letters |
| Broker | A Kafka server that stores messages and answers requests | A post office building |
| Topic | A named category of messages | A labelled mailbox type, such as “orders” |
| Partition | One ordered slice of a topic, kept as files on one broker | One queue at the post office |
| Leader | The broker copy of a partition that handles all reads and writes | The clerk in charge of that queue |
| Follower | Another broker copy that keeps up by copying from the leader | A backup clerk with a duplicate ledger |
| Replication factor | How many copies of each partition exist | Three ledgers in three buildings |
| Consumer | A program that reads messages | The person collecting letters |
| Batch | A group of messages sent together in one request | A bundle of letters tied with string |
A topic is like a big sorting office with many counters. Each counter is a partition. Each counter has one clerk in charge (the leader) and two others keeping duplicate books (followers). Producers hand parcels to the clerk in charge. Consumers ask the clerk for parcels to collect.
Two facts that shape every ceiling
Only the leader talks to clients
Producers and consumers send requests to the leader of each partition. Followers do not answer normal client reads. So the leaders of the busiest partitions carry the client load.
Followers copy from the leader
Followers ask the leader for new data all the time, exactly like a consumer would. So every message written once by a producer is also read and written again on other brokers.
Because of fact 2, the work the cluster does is always larger than the data your applications send. That extra work is called amplification, and we will measure it carefully later.
What Throughput and Ceiling Really Mean
Three measurements that people often mix up.
| Measurement | What it counts | Unit | Everyday picture |
|---|---|---|---|
| Message rate | How many messages per second | Messages per second | Letters posted per minute |
| Byte throughput | How much data per second | Megabytes per second | Kilograms of mail per minute |
| Latency | How long one message takes to be accepted or delivered | Milliseconds | Time for one letter to arrive |
A system can be excellent at one and poor at another. Sending millions of tiny messages stresses the processor and the request handling. Sending fewer huge messages stresses the network and the disk. Very fast delivery of each message (low latency) often means waiting less to form bundles, which lowers throughput. So we always say which measurement we mean, and we always state the message size.
The word “ceiling”
The throughput ceiling is the highest steady rate at which the system can accept data before something gets worse in a way you care about: queues start to grow, latency rises sharply, or requests time out. Notice the word “steady.” A machine may briefly go faster by using up stored energy, such as burst credits in the cloud, but that is not a ceiling you can live on.
The word “saturation”
A part is saturated when it is busy all the time and has no idle moments left. A saturated part becomes the bottleneck: the narrowest point that limits everything else. The whole game of ceiling analysis is finding the part that saturates first.
A supermarket has ten checkout lanes, but only one bagging worker. Customers pile up at the bagging area while cashiers wait. The bagging worker is saturated. Hiring more cashiers is useless. Adding a second bagger doubles the shop’s speed.
Latency does not rise gently as you approach the ceiling. It stays flat for a long time, and then shoots up quickly. This is why a system at 95 percent of its ceiling feels fine right until it does not.
The Journey of One Message
Every step on this path has a speed limit.
flowchart LR
APP["Application creates a message"] --> SER["Producer turns it into bytes and picks a partition"]
SER --> ACC["Message waits in a batch in the producer buffer"]
ACC --> SND["Sender thread ships the batch over the network"]
SND --> NET1["Network to the leader broker"]
NET1 --> RQ["Broker network thread reads it and puts it in a queue"]
RQ --> IO["Broker worker thread validates and appends it to the log"]
IO --> PC[("Operating system page cache then disk")]
PC --> REP["Follower brokers fetch and copy it"]
REP --> ACK["Leader acknowledges to the producer"]
PC --> CON["Consumers fetch it from the leader"]
Create and serialize
The application builds a message. The producer library turns the key and value into bytes and chooses the partition. This uses processor time on the producer machine.
Wait in the batch
The producer does not send each message alone. It collects messages for the same partition into a batch held in memory, and sends the batch when it is full or when a short wait expires.
Ship over the network
A background sender thread groups batches by destination broker and sends them in requests. The network between producer and broker has a limit.
Broker receives
A broker network thread reads the request and puts it in a waiting line. A worker thread takes it, checks it, and writes it to the log.
Write to storage
The write goes first into the operating system’s memory cache and is flushed to the disk in the background. The disk has a write speed limit.
Replicate
Followers fetch the new data and write it to their own disks. The producer can be told “done” only when enough followers have it, depending on its settings.
Read out
Consumers fetch the data from the leader. Each consumer group means another copy of the data leaving the broker’s network card.
Sending a parcel involves packing it, waiting for the courier’s pickup round, the truck ride, the sorting center, the warehouse shelf, and the copy of the receipt sent to head office. Each stage has its own capacity, and the total speed is that of the slowest one.
The Chain of Limits: Finding the Weakest Link
Six resources can each become the ceiling.
| Resource | Where it lives | What limits it | How it feels when saturated |
|---|---|---|---|
| Producer processor and memory | Application machine | Serialization, compression, buffer size | Producer blocks or throws buffer-full errors |
| Producer to broker network | Between machines | Network card and link speed | Send requests take long |
| Broker request handling | Broker threads and queues | Number and speed of threads | Request queue grows, requests wait |
| Broker disk | Broker storage | Write speed and operations per second | Flush delays, slow appends |
| Broker network (in and out) | Broker network card | Client traffic plus replication plus consumers | Everything slows together |
| Consumer side | Reader machines | Processing speed and fetch size | Lag grows, page cache goes cold |
A chain of six people passing buckets of water. The line moves at the speed of the slowest person. If you give the fastest person a bigger bucket, nothing changes. You must find the one who is tired.
The rule of the moving bottleneck
When you fix one limit, the next one becomes the new ceiling. Upgrading disks may reveal that the network card was the next limit. This is normal. A ceiling analysis is not one measurement but a small series: measure, find the weakest link, lift it, measure again. You stop when the ceiling is high enough for your needs, with comfortable room to spare.
Ask three questions in order: What is saturated? By how much? What is the next limit after that? These three answers make a complete capacity plan.
The Producer Side: Batching Is Everything
The single biggest lever on the producer is how messages are grouped.
Sending one small message in one request is very wasteful. Each request has fixed costs: headers, waiting for the response, and work for the broker to parse it. If your message is 200 bytes and the overhead is comparable, most of the effort goes to overhead. Batching spreads that fixed cost over many messages.
| Setting (idea) | What it controls | Effect on throughput | Effect on latency |
|---|---|---|---|
| Batch size | Maximum bytes collected for one partition before sending | Larger batches raise throughput, up to a point | Can rise if batches wait to fill |
| Linger time | How long the producer waits for more messages before sending a not-yet-full batch | A small wait creates fuller batches and raises throughput | Adds up to that wait to each message |
| Buffer memory | Total memory for all waiting batches | Too small blocks the application at high rates | Blocking shows up as long send calls |
| Maximum request size | Largest request the producer will send | Caps how much data one request can carry | Little |
| In-flight requests | How many requests can be outstanding per broker connection | More in flight hides network delay | Little, but ordering needs care |
A delivery van that leaves the depot with one parcel every time is very expensive. A van that waits a few minutes to fill up costs far less per parcel, though each parcel leaves a little later. Linger time is how long the driver waits before leaving.
Batches are formed per partition. If a topic has many partitions and each gets only a trickle of messages, batches stay small even with a large batch size setting. Many partitions plus low traffic per partition equals many small batches.
How to tell if batching is the problem
Producers expose measurements for average batch size and for the number of records per request. If the average batch size is far below the configured maximum, and the linger time is zero, batches are leaving nearly empty. Raising the linger time by a few milliseconds often gives a large throughput gain with almost no visible latency cost. Recent Kafka versions have raised the default linger time above zero for exactly this reason, but older clusters and applications often still use zero.
Compression: Trading Processor for Bandwidth
Smaller data means less network and less disk, at the price of some processor work.
Producers can compress each batch before sending. The broker usually stores the batch as it arrived, still compressed, and consumers decompress on their side. This means one act of compression saves network on the way in, disk on the broker, replication traffic, and network on the way out. That is why compression is one of the strongest ways to raise a ceiling caused by network or disk.
| Choice | Speed of compressing | How small the data gets | Good when |
|---|---|---|---|
| None | No cost | Not smaller | Data is already compressed, such as images, or processors are the limit |
| Light and fast choices (for example LZ4 or Snappy) | Very fast | Moderately smaller | You want a good gain with little processor cost |
| Zstandard | Medium to fast | Usually much smaller | Disk or network is the limit and you can afford some processor |
| Gzip | Slower | Small | Bandwidth is scarce and processors are plentiful |
Vacuum-packing clothes for a suitcase takes a minute of effort at home, but fits far more into the same luggage and pays off at every airport and taxi ride afterward.
Why bigger batches compress better
Compression finds repeated patterns. A batch of one message has few patterns to find. A batch of five hundred similar messages, such as JSON with the same field names, has many, and shrinks dramatically. So compression and batching help each other.
If a broker is set to use a different compression type than the producer, it must decompress and recompress every batch. This uses a lot of broker processor time and can quietly become the ceiling. Keep the producer’s choice and the topic’s setting aligned, or let the broker keep the producer’s choice.
Acknowledgments and Safety Settings
How safe you want each message to be changes how fast the system can go.
After sending a batch, the producer can wait for different levels of confirmation. This setting is usually called acknowledgments, or “acks.”
| Level | The producer waits until | Speed | Risk of losing data |
|---|---|---|---|
| No wait | The data is handed to the network | Fastest | High, since a lost request is never noticed |
| Leader only | The leader has written it | Faster | Some, if the leader fails before followers copy |
| All in-sync copies | Every in-sync replica has it | Slower per request | Lowest |
Sending a package with no tracking, with delivery-to-door confirmation, or with signatures from every office that must hold a copy. Each option is safer and slower than the last.
Does safety lower the ceiling?
Surprisingly, the ceiling for bytes per second is often similar for all three levels, because the followers copy the data anyway. What changes is the waiting time per request. Because the producer waits longer for each batch, it needs more requests in flight or bigger batches to keep the pipe full. If your settings allow only one or two requests in flight and the acknowledgment takes 10 milliseconds, the producer simply cannot send faster than one batch every 10 milliseconds per connection, no matter how strong the machines are.
A simple rule: the maximum rate of one connection is about the batch size times the number of requests in flight, divided by the round-trip time. Longer round trips, such as across regions, need larger batches or more in flight.
Idempotence and order
Modern producers by default number every batch, so that a retry never creates a duplicate. This is called idempotence. It allows several requests in flight while still keeping order for a partition, so it usually does not hurt throughput and is a good default to keep on.
Producer Threads, Connections, and Serialization
Sometimes the producer’s own machine is the bottleneck without anyone noticing.
A Kafka producer object has one background sender thread. That thread builds requests and sends them to every broker. In most programs this is enough. In very fast programs, that single thread, or the serialization and compression done before it, can become saturated. The tell-tale sign is a producer machine with one processor core at 100 percent while the others are idle, and brokers that are barely working.
Brokers idle, producer slow
Check the producer’s own processor. Serialization of large or complicated objects can cost more than the network transfer.
Send calls block
The buffer memory is full because batches leave slower than messages arrive. Either the sender or the broker is behind.
Share one producer per program
Producers are safe to share among threads. Creating many tiny producers wastes connections and makes small batches.
Scale out the producers
Run more producer instances on more machines. Each has its own sender thread and its own network card.
One courier can only carry so many parcels, however big the warehouse is. When the courier is the limit, hire more couriers instead of building more warehouses.
Connections per broker
The producer keeps one connection to each broker it needs. Requests to one broker share that connection, so latency on that single connection can limit the rate to that broker. Spreading data over partitions on many brokers gives the producer many independent connections working at the same time.
The Network Ceiling
Every byte crosses a network card several times.
A network card has a fixed speed, such as 10 gigabits per second. A gigabit is a billion bits, and there are eight bits in a byte, so 10 gigabits per second is about 1.25 gigabytes per second at best. In practice, protocol overhead and other factors leave roughly 85 to 90 percent usable. A network card also works in two directions: inbound and outbound, and modern cards handle both at the same time, each with its own limit.
| Link speed | Best-case bytes per second | Practical planning value |
|---|---|---|
| 1 gigabit | About 125 megabytes | About 100 megabytes |
| 10 gigabits | About 1,250 megabytes | About 1,000 megabytes |
| 25 gigabits | About 3,125 megabytes | About 2,600 megabytes |
| 100 gigabits | About 12,500 megabytes | About 10,500 megabytes |
A two-way road with a fixed number of lanes in each direction. Trucks going in and trucks going out do not block each other, but each direction has its own limit.
Why the network fills up faster than you expect
With three copies of every partition, each producer byte enters one broker (the leader) and then leaves that broker twice, once for each follower. Consumers also pull the data out, once per consumer group. So the outbound side of a broker’s network card carries far more than the inbound side. We will do the exact arithmetic in a later chapter, but the key idea is already clear: outbound traffic is usually the first network limit to be reached.
In the cloud, the advertised network speed of a machine is often a “burst” figure. The steady baseline can be much lower. Test for at least half an hour so you measure the baseline, not the burst.
The Disk Ceiling: Why Kafka Loves Sequential Writes
Kafka is fast on disks because it treats them politely.
A partition is stored as a log: new messages are always added to the end of a file. Writing to the end of a file is a sequential write, meaning the disk head or the flash memory writes along a straight line and does not jump around. Sequential writes are much faster than random ones, especially on spinning disks, and are still helpful on modern solid-state drives.
Writing in a diary, adding each new line after the last, is quick. Writing each new note into a random page of a thick book, hunting for the right spot each time, is slow.
Append to the active segment
Each partition is split into files called segments. New messages go to the last one only.
Land in the page cache
The operating system first keeps the written bytes in memory. The application is told the write is done at this point.
Flush in the background
The operating system writes dirty memory pages to the disk in batches, on its own schedule. Kafka usually does not force each write to disk, because safety comes from replication.
Disk speed sets the long-run limit
Memory can absorb a burst, but in the long run every byte accepted must be written to disk. The steady disk write speed is the real ceiling.
Numbers to remember
| Storage type | Typical sustained sequential write | Comment |
|---|---|---|
| Single spinning disk | 100 to 200 megabytes per second | Often used in groups, one directory per disk |
| Network-attached cloud volume | Set by a purchased limit, often 125 to 1,000 megabytes per second | The purchased limit is the ceiling, and it can be shared with the network |
| Local solid-state drive | Several hundred to a few thousand megabytes per second | Highest speed, but data is lost if the machine is lost, so replication matters |
These are typical ranges, not promises. Always measure the actual disk that will hold your logs, with the real workload.
Page Cache and Zero-Copy: Kafka’s Speed Secrets
Why reads are often much cheaper than you would guess.
Kafka does not keep its own big cache of messages. It leans on the operating system’s page cache, which is free memory that the operating system uses to hold recently used file contents. When a consumer reads data that was just written, the data is usually still in the page cache, so no disk read is needed at all.
A librarian keeps the books people just returned on a cart near the desk. The next borrower who asks for one gets it at once, without a walk to the far shelves.
Zero-copy: skipping the middle steps
Normally, sending a file over a network means copying bytes several times: from disk to the operating system’s memory, then to the application’s memory, then back to the operating system for the network card. Kafka can ask the operating system to send data straight from the page cache to the network card without passing through the application. This is called zero-copy, and it saves processor time and memory bandwidth.
Consumer asks for data
The broker finds the right position in the log file.
Data is in the page cache
If the consumer is keeping up, it is there already. If not, the operating system reads it from the disk first.
Direct hand-off
The operating system sends the bytes from cache to the network card directly.
Zero-copy is lost when the broker must look at or change the data on the way out, for example when encrypting with TLS inside the broker process, or converting between old and new message formats. Then the data passes through the broker’s own memory and the processor works much harder.
The slow reader problem
A consumer far behind, for instance one replaying last week’s data, forces disk reads. Those reads also fill the page cache with old data, pushing out the fresh data that other consumers and followers need. This can make everything slower at once. Ceiling tests must include the situation where some readers are behind.
Inside the Broker: Threads and Queues
A broker is a small factory with three stations.
Inside a broker, requests pass through three stages. Understanding them explains a ceiling that is easy to miss: the broker can run out of thread time even when the disk and network are fine.
flowchart LR
CL["Clients and followers"] --> AC["Acceptor accepts new connections"]
AC --> NT["Network threads - read requests and write responses"]
NT --> RQ[("Request queue - bounded")]
RQ --> IT["I/O threads - process requests: append to log, read from log"]
IT --> LOG[("Log files and page cache")]
IT --> PG["Purgatory - waits for followers or for more data"]
PG --> RS[("Response queue per network thread")]
IT --> RS
RS --> NT
NT --> CL
| Stage | Job | Setting (idea) | When it saturates |
|---|---|---|---|
| Network threads | Read bytes from sockets, build requests, and later send responses | Number of network threads | Many connections or heavy TLS work, network thread idle percentage falls near zero |
| Request queue | Holds requests waiting for a worker | Maximum queued requests | Full queue makes network threads stop reading, so clients wait |
| I/O threads | Do the real work: write to the log, read from it, validate | Number of I/O threads | Request handler idle percentage falls near zero |
| Purgatory | Parks requests that cannot finish yet, such as produce requests waiting for followers | Wait times in the requests | Many parked requests hold resources |
| Response queue | Holds finished responses waiting to be sent | Per network thread | Slow clients or network |
A busy bank has greeters at the door (network threads), a waiting area with numbered tickets (the request queue), tellers who do the work (I/O threads), and a side room for customers who must wait for a manager’s approval (purgatory). The bank is limited by whichever group is too small for the crowd.
Two numbers tell you a lot: how idle the network threads are, and how idle the I/O threads are. When either drops below about 30 percent idle, the broker is close to its thread ceiling.
Request Time Breakdown: Where Does the Time Go?
Every request’s total time can be split into five parts, and the biggest part is the culprit.
Brokers measure how long requests spend in each stage. For a produce request, the total time is the sum of the following parts:
Request queue time
Waiting for a free I/O thread. A large value means the I/O threads are too few or too slow.
Local time
The leader writing to its own log. A large value points at the disk or at the page cache being under pressure.
Remote time
Waiting for followers to copy the data. A large value points at slow followers, network trouble, or overloaded other brokers.
Response queue time
Waiting for a network thread to send the answer. A large value means network threads are busy.
Response send time
Actually pushing the response out. A large value indicates slow clients or a full network.
| Biggest slice | Most likely bottleneck | First action |
|---|---|---|
| Request queue | Not enough I/O thread capacity | Check processor use; raise the thread count if processors are free |
| Local | Disk or page cache | Check disk write speed and wait times |
| Remote | Replication path | Check follower brokers and network |
| Response queue or send | Network threads or network card | Check network thread idle and network use |
A hospital measures how long a patient waits at reception, in the exam room, at the lab, and at the pharmacy. Whichever stage takes the longest is where to add staff.
This breakdown is the most powerful single tool in a broker-side ceiling analysis. It turns “Kafka is slow” into “the leader waits about 20 milliseconds for followers,” which is something you can act on.
Replication: The Hidden Multiplier
Every byte written is written again on other brokers.
Followers stay in sync by sending fetch requests to the leader, exactly like consumers. The leader replies with new data, and the follower appends it to its own log. The leader keeps a list of followers that are close enough to be called in-sync replicas. With the strongest acknowledgment setting, a write is confirmed only when all in-sync replicas have it.
Disk writes multiply
With three copies, the cluster writes three times the producer data to disks, spread over three brokers.
Network traffic multiplies
Two extra copies travel from leaders to followers. That traffic uses both the leader’s outbound and the follower’s inbound capacity.
Latency depends on the slowest follower
With full acknowledgment, the request finishes only when the slowest in-sync follower has copied the data.
Safety and failover
If a broker is lost, another already holds the data, and reads and writes continue.
A company that makes three photocopies of every contract, and stores each in a different building, spends three times on paper and delivery. In exchange, a fire in one building never destroys a contract.
Follower fetching and its own limits
Followers use a small number of fetcher threads per source broker. Each fetch request has a maximum size. If a follower must catch up on a very busy partition with only one fetcher thread, that one thread can become the limit, and the follower can fall out of the in-sync list. When that happens, writes with full acknowledgment may be refused if too few replicas remain in sync. So replication has its own ceiling, separate from the client-facing ceiling.
A steady rise in the number of under-replicated partitions during a load test is a clear sign that followers cannot keep up. You have reached the replication ceiling, even if producer numbers still look fine.
The Amplification Arithmetic
Simple formulas that predict broker network and disk load.
Let P be the total rate at which producers send data to the whole cluster, in megabytes per second. Let R be the replication factor (number of copies), and C the number of consumer groups that each read everything. Let N be the number of brokers, and assume load is spread evenly. Compression is already counted in P, since we measure bytes on the wire.
| Quantity (whole cluster) | Formula in words | Example: P=300, R=3, C=2 |
|---|---|---|
| Disk writes | P times R | 900 megabytes per second |
| Network inbound (all brokers together) | P (from producers) plus P times (R minus 1) (from leaders to followers), which equals P times R | 900 megabytes per second |
| Network outbound (all brokers together) | P times (R minus 1) for replication plus P times C for consumers | 600 plus 600 = 1,200 megabytes per second |
Now divide by the number of brokers to get the load on each. If N equals 6:
| Per broker | Result |
|---|---|
| Disk writes | 900 divided by 6 = 150 megabytes per second |
| Inbound network | 900 divided by 6 = 150 megabytes per second |
| Outbound network | 1,200 divided by 6 = 200 megabytes per second |
If a newspaper is delivered to one house and two backup copies are posted to two other houses, then two neighbors also want to read it, the postal service moves the paper five times, even though the printer only made one.
Finding the ceiling from the arithmetic
Now reverse the question. Suppose each broker can write 400 megabytes per second to disk, and can send about 1,000 megabytes per second out of its network card in practice. Then:
Disk limit
Per broker disk load is P times R divided by N. Setting it equal to 400 with R equal to 3 and N equal to 6 gives P equal to 800 megabytes per second.
Outbound network limit
Per broker outbound is P times (R minus 1 plus C) divided by N. With C equal to 2, that is P times 4 divided by 6. Setting it equal to 1,000 gives P equal to 1,500 megabytes per second.
Inbound network limit
Per broker inbound is P times R divided by N, so P equal to 2,000 megabytes per second at 1,000 per broker.
The smallest wins
The disk limit of 800 is the lowest, so the disk is the bottleneck, and the cluster ceiling is about 800 megabytes per second.
Compute all three limits and take the smallest. That tells you both the ceiling and which resource to upgrade first. Upgrading the network in this example would change nothing, until the disk is improved.
Planning for Failure: The N-Minus-One Rule
A cluster that is exactly at its ceiling cannot survive a single broker failure.
When a broker stops, its leaders move to other brokers, and its share of the load is spread over the survivors. In our six-broker example, five brokers must now carry what six carried. The per-broker load rises by one-fifth (six divided by five is 1.2 times), and during recovery, the restarted broker must also catch up on missed data, adding extra replication traffic.
| Situation | Brokers | Disk ceiling for P (400 per broker, R=3) |
|---|---|---|
| All healthy | 6 | 800 megabytes per second |
| One broker down | 5 | About 667 megabytes per second |
| Two brokers down | 4 | About 533 megabytes per second |
A team of six lifts a heavy table together. If one gets sick, the other five must lift the same table. If they were already at their limit with six, they drop it with five.
How to plan
Decide how many failures to survive
Most teams choose one broker, or one whole zone.
Compute the ceiling with those brokers gone
Use the same formulas with the reduced number.
Keep normal traffic well below that
A common target is to run at 60 to 70 percent of the reduced ceiling in normal times, leaving room for spikes and recovery traffic.
If you lose a whole availability zone in a three-zone cluster, you lose a third of the brokers at once. Your planning number is then two-thirds of the healthy ceiling, not five-sixths.
Partitions and Leader Placement
Where the leaders live decides who does the work.
The arithmetic above assumed that load is spread evenly. In real clusters it rarely is. Leaders handle all client traffic for their partitions, so a broker with more leaders, or with the busiest partitions, carries more load and reaches its ceiling first. The cluster’s ceiling is really the ceiling of its busiest broker.
Partitions below parallelism
If a topic has fewer partitions than brokers, some brokers get no leader for it at all. A single partition can be written by only one leader at a time.
Several per broker
A few partitions per broker for each busy topic lets load spread evenly and lets more threads work in parallel.
Overhead grows
Each partition adds files, memory, and replication fetch work. Tens of thousands per broker slow recovery and add background load.
Leader distribution
After restarts, leaders can pile up on a few brokers. Preferred leader election moves them back to their intended homes.
A shop with eight checkout lanes but a queue that forms only in front of lanes one and two. The shop has capacity for eight, but the customers behave as if only two exist.
The single-partition ceiling
One partition’s leader appends to one log, handled by one broker. The maximum speed of a single partition is therefore limited by that broker’s disk and by the way requests for that partition are handled. It is common for a single partition to peak at some tens of megabytes per second. If you need more for one topic, you need more partitions, so that many leaders share the work.
Skew: Hot Partitions and Hot Brokers
A few busy keys can spoil an otherwise balanced cluster.
Messages with the same key always go to the same partition. If one key is far busier than others, for example a very large customer or a default key like “unknown,” its partition receives a huge share of the traffic. That partition’s leader broker gets hot while the others are relaxed. Adding brokers does not help, because the hot key still lands on one partition on one broker.
| Type of skew | Cause | Sign | Remedy |
|---|---|---|---|
| Key skew | A few keys carry most messages | One partition much larger and busier than others | Change the key design, or add a random suffix to spread hot keys, if order allows |
| Leader skew | Leaders concentrated on few brokers | One broker has more leaders | Preferred leader election, or a balancing tool |
| Topic skew | Busy topics have too few partitions | Busy topic spans only a few brokers | Add partitions, with care for ordering |
| Consumer skew | Readers concentrated on one broker’s partitions | One broker’s outbound network is highest | Spread partitions and readers |
A concert with ten entrance gates, but most fans hold tickets for gate three. Opening more gates elsewhere does not shorten the queue at gate three.
Always look at per-broker and per-partition graphs, not only cluster totals. Averages hide the hot spots that set the real ceiling.
Consumers and Fan-Out
Reading is part of the ceiling too, and it grows with the number of readers.
Every consumer group reads the full stream, so each additional group multiplies outbound traffic. Ten groups reading the same topic mean ten copies leave the brokers. Data that is still in the page cache costs little processor and no disk. Data that must be read from the disk costs disk reads on top of writes.
Outbound grows with groups
Plan for C groups in the formula. Also plan for future groups such as analytics, search indexing, and backups.
Small fetches waste effort
Consumers asking for tiny amounts often create many small requests. Waiting for a minimum amount of data per fetch reduces broker work.
Behind means cold reads
A consumer that falls behind reads old data from disk, which competes with writes for the disk and disturbs the cache.
Followers are consumers too
The replication traffic is nearly identical to consumer traffic, and shares the same request threads.
A magazine with more subscribers needs more copies printed and posted. The presses are unchanged, but the post room is much busier.
Because consumers are so similar to followers, a busy read side can slow replication, and slow replication can slow producers who wait for full acknowledgment. The read side and the write side are connected through shared threads, disks, and network.
Encryption, Format Conversion, and Other Hidden Taxes
Some features quietly lower the ceiling.
| Feature | Extra work created | Effect on ceiling | Mitigation |
|---|---|---|---|
| TLS encryption on client and replication links | Encrypting and decrypting all data in the broker process, and loss of zero-copy | Processor becomes the limit earlier; network threads work harder | Use hardware acceleration where available, more network threads, and more processor cores |
| Compression mismatch | Broker decompresses and recompresses | Sharp drop in throughput | Align compression settings |
| Old client message formats | Broker converts on the fly | Loss of zero-copy for those reads | Upgrade clients |
| Authorization and quota checks | Small extra work per request | Matters with huge request counts | Prefer larger batches and fewer requests |
| Detailed logging and metrics | Writing logs and computing measurements | Small, but real on busy brokers | Keep debug logging off in production |
| Other programs on the same machine | Compete for processor, memory, and disk | Unpredictable | Dedicate machines to brokers |
A courier who must open every parcel, inspect it, and reseal it can carry far fewer parcels a day than one who just moves sealed boxes.
Ceiling tests done with security turned off can overstate production capacity by a large margin. Always test with the same encryption, authentication, and quota settings you will use in production.
Quotas: Ceilings You Set on Purpose
Sometimes the ceiling is a rule, not a machine.
Kafka can limit how much data a client, user, or group of clients may send or receive per second. It can also limit how much processor time a client may use in the request handling threads. These quotas protect the cluster from one noisy application starving all the others.
The broker measures usage
For each client identity, the broker keeps a running average of bytes per second over a short window.
It compares with the quota
If a client goes over its limit, the broker calculates a delay.
It delays the response
Instead of refusing, the broker holds the response for that time and asks the client to slow down. The client’s throughput drops to the quota.
A water company limits how much each factory can draw from the main during the day, so that homes still have pressure. A factory that draws too much finds its tap running slower.
If one application seems stuck at a suspiciously round number of megabytes per second while brokers are idle, suspect a quota before you suspect hardware. Client-side throttle-time metrics reveal it.
Throughput Versus Latency: The Knee of the Curve
Why speed feels fine, and then suddenly does not.
As you push more load into a system, three zones appear. In the first zone, everything is smooth: more load means more throughput, and latency stays flat. In the second zone, queues begin to form, and latency slowly rises. In the third zone, the system is saturated: throughput stops growing no matter how hard you push, and latency climbs steeply, often ending in timeouts. The bend between the second and third zones is called the knee.
flowchart LR
Z1["Zone 1 - light load: throughput rises with load, latency flat, plenty of idle time"]
Z2["Zone 2 - busy: throughput still rises, queues start, latency creeps up"]
KN{"The knee - one resource is nearly always busy"}
Z3["Zone 3 - saturated: throughput flat, queues grow, latency spikes, timeouts and retries begin"]
Z1 --> Z2 --> KN --> Z3
Z3 -->|"retries add even more load"| Z3
A road at night is empty and fast. At rush hour it is busy but moving. Add just a few more cars and it becomes a standstill. The last few cars did not add a little delay; they caused a jam that lasts for an hour.
Why saturation is dangerous
Once a resource is saturated, requests wait in queues. Waiting requests can time out. The clients then retry, which creates even more requests. The extra load makes the queue longer, so more time-outs happen. This loop is called a retry storm, and it can keep a system down even after the original spike has ended.
Define the ceiling as the load where latency is still acceptable, not the load where the system finally breaks. A test that only reports the peak megabytes per second, without the latency at that level, hides the knee.
The batching trade
Batching moves you along this curve in an interesting way. Longer waits for batches raise throughput, since the overhead is shared, but add a fixed delay to every message. The best setting is the smallest wait that gets the throughput you need, and it depends on how quickly your application needs each message delivered.
How to Measure Your Ceiling: The Method
A step-by-step recipe that anyone on your team can repeat.
Build a realistic test cluster
Use the same machine types, disks, network, number of brokers, replication factor, and security settings as production, or a scaled-down copy whose scaling you understand.
Create realistic topics
Use the real number of partitions, the real replication factor, and the real minimum in-sync setting. Spread leaders evenly before starting.
Describe the workload
Write down message size (average and spread), key distribution, compression, acknowledgment level, and how many consumer groups read.
Use a load generator
Kafka ships with simple performance test tools for producers and consumers. Other load tools exist too. Run several generator machines so the generators are never the limit.
Step the load up
Start low, and raise the target rate in steps, holding each step for several minutes. Record throughput, latency at several percentiles, and every resource measurement at each step.
Find the knee
The knee is the step at which latency rises sharply or queues begin to grow. Your ceiling is just below it.
Identify the saturated resource
At the knee, see which resource is nearly always busy: a disk, a network card, processor cores, or broker thread idle percentages.
Soak test
Hold a level around 70 percent of the ceiling for several hours. Some limits, like cloud burst credits and disk cleanup work, only show up over time.
Repeat with a failure
Stop one broker during a run at your normal peak level and see whether latency remains acceptable.
Testing a bridge means adding weight bit by bit, watching how it bends, and stopping well before it breaks. You then publish a safe load limit that is lower than the breaking point.
Keep a written test record: the setup, the settings, the results at every step, and the conclusion. Next year, when traffic has doubled, this record makes the next analysis quick.
Common Test Mistakes
Bad tests give confident, wrong answers.
| Mistake | Why it misleads | Better practice |
|---|---|---|
| Random or repeated identical payloads | Compression results are either too poor or too good | Use data that looks like real messages |
| Single fixed message size | Real traffic has a mix of sizes | Test with the real distribution |
| Load generator on one small machine | The generator becomes the bottleneck | Use several strong generators and watch their processors |
| Short runs of one minute | Caches and burst credits hide the steady state | Run long enough for the steady state |
| Testing only writes | Real clusters also serve readers and followers | Run consumers alongside |
| Empty topics only | Real brokers hold old data, and cleanup and retention work happens | Test with a realistic amount of stored data |
| Reporting the average latency | Averages hide slow requests | Report high percentiles such as the 99th |
| Skipping the failure test | Normal-day results are not failure results | Test with a broker removed |
Testing a car’s fuel economy only downhill, with an empty boot, and with a tail wind gives a lovely number that no real driver ever gets.
The most common surprise: the test data compresses ten times better than real data, so the test shows a network ceiling far above what production can reach. Use samples of real messages whenever you are allowed to.
Reading the Results: A Bottleneck Decision Tree
A simple path from symptom to the limiting resource.
flowchart TB
S["Throughput stops rising and latency climbs"] --> Q1{"Are producer machines busy - processor near full or buffer full?"}
Q1 -->|"Yes"| A1["Producer-side ceiling: batching, compression, serialization, or too few producer instances"]
Q1 -->|"No"| Q2{"Are broker network threads or I/O threads almost never idle?"}
Q2 -->|"Yes"| A2["Broker thread ceiling: more threads if processors are free, or fewer and larger requests, or add brokers"]
Q2 -->|"No"| Q3{"Is a broker network card near its limit in either direction?"}
Q3 -->|"Yes"| A3["Network ceiling: compress, spread leaders, add brokers, or upgrade network"]
Q3 -->|"No"| Q4{"Is disk write speed or disk wait time at its limit?"}
Q4 -->|"Yes"| A4["Disk ceiling: faster or more disks, more brokers, or less replication traffic"]
Q4 -->|"No"| Q5{"Are followers falling behind - under-replicated partitions growing?"}
Q5 -->|"Yes"| A5["Replication ceiling: more fetcher threads, check slow follower and cross-zone links"]
Q5 -->|"No"| A6["Look for quotas, skew on one hot partition, or a slow client and consumer side"]
A doctor asks a fixed series of questions, from the most common cause to the rare ones. You follow the same discipline: check the simplest and most likely limits first.
Reading it correctly
Look at the busiest broker
Use per-broker numbers, not averages.
Watch several resources at once
Two resources can be close to saturation together, and fixing only one gives a small gain.
Change one thing at a time
Change a single setting, rerun the same step, and compare. Several changes at once hide which one helped.
Worked Example: Many Small Messages
When the count of messages, not the bytes, sets the ceiling.
A metrics collector sends 1,000,000 tiny messages per second, each 100 bytes. The byte rate is only about 100 megabytes per second, small compared with disks and networks. Yet the producers struggle and the brokers show high processor use. What is going on?
| Step | Observation | Meaning |
|---|---|---|
| 1 | Average batch holds only 3 messages | Batches leave nearly empty because the linger time is zero and there are many partitions |
| 2 | That means about 330,000 batches per second | Each batch is a unit of work for producer, network, and broker |
| 3 | Broker I/O threads are 90 percent busy | The work per request, not the bytes, is the limit |
| 4 | Disk and network are less than 20 percent used | Those resources are not the problem |
The fix
Add a small linger time
A wait of 5 to 20 milliseconds lets each batch collect hundreds of messages.
Raise the batch size
Allow batches of hundreds of kilobytes, so a full batch is not cut short.
Turn on light compression
Repeated field names compress very well in larger batches.
Reduce the partition count if it is needlessly high
Fewer partitions per producer means fuller batches for the same message rate.
After the changes, batches carry about 300 messages. The requests per second fall from about 330,000 to about 3,300, a hundred times fewer, and the I/O threads drop from 90 percent busy to about 10 percent. The ceiling is now far higher, and it is set by the disk and network again, as it should be.
Sending a million postcards each in its own envelope by its own courier overwhelms the post office. Sending them in a few thousand bundles is trivial for the same post office.
Worked Example: Big Messages and Slow Followers
A different workload with a different bottleneck.
An image-processing platform sends 2-megabyte messages at 400 per second, giving 800 megabytes per second, with 3 copies on 9 brokers. Per-broker disk writes are 800 times 3 divided by 9, about 267 megabytes per second. Each broker has a cloud volume purchased for 250 megabytes per second, so disk is already over its limit.
| Check | Calculation | Result |
|---|---|---|
| Disk load per broker | 800 times 3 divided by 9 | About 267 megabytes per second, above 250 |
| Inbound network per broker | Same as disk | About 267, fine for a 10-gigabit card |
| Outbound with 2 consumer groups | 800 times (2 plus 2) divided by 9 | About 356, fine |
| Symptom | Followers lag, under-replicated partitions rise, producers see slow acknowledgments | Disk is the ceiling |
Options, in order of cost
Compress on the producer
If images are already compressed this gains little, but metadata inside messages might compress well. Test on real messages.
Buy a higher volume speed
Raise the purchased disk speed. It costs money but changes no design.
Add brokers
Going from 9 to 12 brokers lowers the disk load per broker to 200 megabytes per second. Partitions must then be moved to use the new brokers.
Rethink the design
Store the large images in object storage and send only a small reference through Kafka. The messages shrink from 2 megabytes to a few hundred bytes, and the ceiling problem nearly vanishes.
Instead of mailing a heavy statue between offices, you keep the statue in a warehouse and mail a small card that says where to find it.
Sometimes the best ceiling lift is not a faster system but less data. Kafka is at its best with small and medium messages, and less comfortable with very large ones.
Cloud-Specific Ceilings
Clouds add limits you cannot see on the machine itself.
| Cloud limit | What it is | Symptom | What to do |
|---|---|---|---|
| Network baseline versus burst | A machine may be allowed a high speed for a short time and a lower steady speed after credits run out | Great results for ten minutes, then a sudden drop | Test for long enough, size on the baseline |
| Volume speed and operations limits | Purchased disk throughput and operations per second | Flat disk write speed at exactly the purchased number | Buy more speed or use more volumes |
| Machine-level storage limit | The machine can only push a certain amount to all volumes together | Adding volumes gives no gain | Choose a larger machine type |
| Cross-zone traffic | Data crossing between zones has cost and sometimes less bandwidth | Higher latency for replicas in other zones and higher bills | Plan copies per zone and consider reading from the nearest replica |
| Noisy neighbors | Other customers on shared hardware | Unexplained slow periods | Use dedicated or larger instance sizes |
| Storage and network share the same path | Network-attached disks use the machine’s network | Disk and network compete | Count disk traffic against the network limit too |
A gym membership that says “unlimited” may still have a fair-use clause. After a certain amount of use in a month, you are slowed. The fine print is the real ceiling.
When storage is network-attached, every byte written to a volume also crosses the machine’s network path. In that case, the inbound network of a broker carries the producer data and the follower data, and the storage traffic takes another share. Check the machine’s documented combined limit.
Raising the Ceiling: Scale Up, Scale Out, or Tune
Three families of remedies, and when each works best.
Change settings
Batching, compression, threads, fetch sizes. Cheap and quick, but limited by hardware. Best when the analysis shows waste, such as tiny batches.
Bigger machines
Faster disks, more processors, faster network. No data movement needed, but you buy capacity you might not need in every dimension.
More brokers
Divides the per-broker load. Requires moving partitions to the new brokers and more operational effort.
Send less data
Better serialization, dropping unused fields, sending references instead of big blobs, or sampling.
| Bottleneck | Best first remedy | Second remedy |
|---|---|---|
| Producer batching | Linger time and batch size | Fewer partitions per producer |
| Producer processor | More producer instances | Faster serialization format |
| Broker threads | More threads if processors are free | Larger batches, more brokers |
| Broker network | Compression | More brokers or faster network |
| Broker disk | Faster or more disks | More brokers, compression |
| Replication lag | More fetcher threads, faster link | Check the slow follower’s hardware |
| Hot partition | Change the key or spread the key | Split the topic by traffic type |
If a shop is too crowded, you can rearrange the shelves (tune), rent a bigger shop (scale up), open a second shop (scale out), or sell fewer bulky items (redesign). Which one is best depends on what is actually causing the crowd.
Adding brokers does not move any existing partitions by itself. Until you rebalance, the new brokers sit idle, and the ceiling of the old ones is unchanged. Remember to plan the data movement and its own cost.
Tiered Storage and Retention Effects
Where old data lives changes what the disk has to do.
By default, all retained data lives on each broker’s local disk. With tiered storage, older segments move to cheaper remote storage, and only recent data stays local. This shrinks the disk size that each broker needs and speeds up recovery and rebalancing, because there is less local data to copy.
New data goes to the local disk
Write ceilings are unchanged. Local disk speed still limits ingest.
Closed segments are uploaded
A background process copies finished segments to remote storage, using extra network and some processor.
Old local copies are removed
Local retention can then be short, which frees space.
Old reads come from remote storage
Consumers replaying history read through the remote tier, which is slower but does not disturb the local page cache as much.
A shop keeps this month’s stock in the front room and sends older stock to a cheap warehouse across town. Serving today’s customers is just as fast, and the front room is never full.
Tiered storage does not raise the write ceiling. It lowers the cost and pain of storing history, and it adds an upload stream that must fit in your network budget.
Retention and cleanup work
Even without tiering, brokers perform background work: deleting old segments, compacting logs for compacted topics, and building indexes. Compaction in particular reads and rewrites data, which uses disk and processor time. When measuring a ceiling for compacted topics, include the cleaner’s work, since it competes with normal traffic.
Sizing the Producer Buffer and Connection Rate
A short calculation that prevents blocked applications.
The producer’s buffer memory holds batches that are waiting or in flight. If it is too small, the application is forced to wait whenever the buffer is full. A rough sizing rule is: the buffer should hold at least the number of partitions the producer writes to, times the batch size, with extra room for batches in flight to brokers.
| Item | Example value | Result |
|---|---|---|
| Partitions written by one producer | 200 | 200 open batches |
| Batch size | 128 kilobytes | About 25 megabytes for open batches |
| Batches in flight (brokers times in-flight requests) | 10 brokers times 5 requests | Up to 50 more batches, about 6 megabytes |
| Suggested minimum buffer | Sum plus a safety margin | Roughly 64 megabytes or more |
A packing table must be large enough to hold one open box for every destination, plus the boxes already waiting for the courier. If the table is too small, packers must stop and wait for space.
The single-connection rate limit
Suppose one connection to a broker sends batches of 128 kilobytes, with 5 requests in flight, and each round trip takes 20 milliseconds. The maximum rate on that connection is 5 times 128 kilobytes per 0.02 seconds, which is 32,000 kilobytes per second, or about 32 megabytes per second. If the same producer talks to a broker in another region with a 100-millisecond round trip, the same setting gives only about 6.4 megabytes per second. Longer distance needs bigger batches or more in flight.
When a producer is slow, brokers are idle, and the round trip is long, the connection itself is the limit. Raise the batch size, allow more requests in flight, or place producers closer to the brokers.
A Simple Capacity Planning Worksheet
Put everything together in seven lines you can fill in for your own cluster.
Write down the peak producer rate
Measure in bytes on the wire, after compression, at your busiest hour, and add expected growth for a year.
Write down the replication factor and consumer groups
Include groups you plan to add in the next year.
Compute per-broker disk, inbound, and outbound load
Use the formulas from the amplification chapter, with the number of brokers minus the failures you want to survive.
Compare each with the measured practical limit
Use limits from your own tests, not from advertising sheets.
Check the threads
Confirm thread idle percentages stay above about 30 percent in the test at that load.
Add the storage size
Multiply daily data by retention days by replication factor, and keep a quarter of the space free.
Pick the plan and the review date
Choose the machine count and type, and set a date to check the numbers again.
A caterer works out plates per hour, ovens, cooks, and delivery vans before an event, checks the smallest of them, and books extra help for the day. The worksheet is that same habit for Kafka.
The storage line often surprises people. Three copies of a week of data at a few hundred megabytes per second is a very large amount of disk, and sometimes storage, not throughput, decides how many brokers you need.
Advantages, Disadvantages, and Trade-offs
Every step that raises the ceiling costs something else.
What you gain by pushing the ceiling up
- Room for growth, spikes, and backfills
- Survival of broker or zone failures
- Lower cost per message when batching and compression are used well
- Fewer late-night incidents
- Clear evidence for budget requests
What it costs
- Larger batches add a small delay to each message
- Compression uses processor time on producers and consumers
- More brokers means more to run, patch, and pay for
- More replicas and stronger acknowledgments add latency
- Testing properly takes time and equipment
| Choice | Raises throughput | Hurts |
|---|---|---|
| Longer linger time | Yes, fuller batches | Per-message delay |
| Stronger compression | Yes, when network or disk limits | Processor use, possibly latency |
| Weaker acknowledgments | Yes, shorter waits | Safety of data |
| Fewer replicas | Yes, less copying | Durability and failover |
| More partitions | Yes, more parallelism | Overhead, recovery time, ordering across partitions |
| More brokers | Yes, load divided | Cost and operations |
| Tiered storage | Not directly | Complexity and remote read speed |
Making a bus faster by removing seats, or removing seat belts, or skipping stops changes speed but also comfort, safety, and service. The right choice depends on what matters most for that route.
Never buy speed by lowering safety without a clear decision from the people who own the data. A bigger number on a dashboard is not worth lost payments or lost orders.
Security and Its Effect on Throughput
Protecting data costs capacity, and that cost should be planned rather than discovered.
| Protection | What it does | Throughput effect |
|---|---|---|
| Encryption in transit (TLS) | Scrambles data on the network so eavesdroppers cannot read it | Extra processor work on brokers and clients, and loss of zero-copy on reads |
| Authentication | Proves who a client is when it connects | Small cost per connection; matters when clients reconnect very often |
| Authorization | Checks whether a client may do an action | Small cost per request; keep rules simple and use groups |
| Quotas | Limit how much a client may send or read | Deliberate ceiling per client; protects others |
| Encryption at rest | Encrypts disk contents, usually below Kafka at the volume level | Usually small with modern hardware |
| Message-level encryption by applications | Applications encrypt values before sending | Encrypted data does not compress, so network and disk load rise |
Armored vans are safer than ordinary vans, but they are heavier, slower, and carry less. That trade is worth making for valuable cargo, as long as you plan the fleet size on the armored van’s real capacity.
Test with security on
Run every ceiling test with the exact encryption and authentication of production.
Give processors room
Encryption shifts the bottleneck toward processor time. Choose machines with enough cores and hardware encryption support.
Guard against noisy clients
Quotas keep one buggy or malicious program from consuming all capacity.
Limit connection storms
Many clients reconnecting at once cost many expensive secure handshakes. Use connection limits and back-off in clients.
Security is not optional to gain speed. The correct approach is to include its cost in the ceiling and buy the capacity needed.
Monitoring, Logging, and Metrics
What to watch so the ceiling never surprises you.
Exact metric names differ between Kafka versions and monitoring tools, so treat this as a map of ideas. Watch each resource in the chain, and watch how close it is to its limit.
| What to watch | Where | Warning sign |
|---|---|---|
| Bytes in and out per broker and per topic | Broker metrics | Close to network limit or uneven between brokers |
| Messages per second per broker | Broker metrics | Very high with low bytes, suggesting tiny batches |
| Network thread idle percentage | Broker metrics | Below about 30 percent |
| Request handler (I/O thread) idle percentage | Broker metrics | Below about 30 percent |
| Request queue size | Broker metrics | Steadily growing or near its maximum |
| Request time by stage (queue, local, remote, response) | Broker metrics | One stage growing over others |
| Disk write speed, disk wait, and free space | Machine metrics | At the purchased or hardware limit |
| Page cache hit and memory pressure | Machine metrics | Reads going to disk more than before |
| Processor use per core | Machine metrics | A few cores at 100 percent |
| Under-replicated partitions and in-sync set shrinks | Broker metrics | Rising during load |
| Leader count per broker | Broker metrics | Uneven counts |
| Producer batch size average and records per request | Producer metrics | Far below configured maximum |
| Producer buffer available and time blocked | Producer metrics | Buffer near empty, blocking time rising |
| Producer request latency and throttle time | Producer metrics | Rising latency or any throttling |
| Consumer lag and fetch rates | Consumer metrics | Lag rising steadily |
A pilot watches many instruments at once: speed, height, fuel, engine temperature. Any single gauge may look fine while another warns of trouble. A good dashboard puts them together.
Alert on headroom, not only on failure
Set a warning at about 60 percent of the ceiling
Time to plan more capacity.
Set an alert at about 75 to 80 percent
Time to act, since a failure or spike would push you over.
Track the trend
A line that grows 5 percent per month reaches the limit on a predictable date. Put that date on the team’s calendar.
Broker logs also help: warnings about slow requests, shrinking in-sync sets, and connection problems often appear in the log minutes before dashboards look bad.
Best Practices and Design Patterns
Habits that keep the ceiling high and the surprises low.
Batch and compress by default
Use a small linger time, a generous batch size, and a light, fast compression choice for text-like data.
Size for N minus one
Plan capacity so that losing a broker or a zone keeps the cluster within its comfort range.
Keep leaders balanced
Watch leader counts and per-broker traffic, and rebalance regularly.
Separate noisy tenants
Use quotas, or even separate clusters, for workloads that behave very differently, such as bulk backfills and low-latency payments.
Reference, not blob
Keep messages small. Put large files in object storage and send links.
Re-test on change
Re-run a ceiling test after major changes in traffic mix, hardware, security settings, or Kafka version.
Dedicated machines
Let brokers have their own machines and disks, without other heavy programs.
Backoff on clients
Clients should slow down and retry with growing waits, to avoid retry storms.
| Practice | Reason |
|---|---|
| Keep the disk for logs separate from the operating system disk | Log traffic should not fight with system activity |
| Leave plenty of free memory for the page cache | The cache is what makes reads cheap |
| Avoid giving Kafka’s own process a huge memory area | Memory taken from the page cache slows reads |
| Keep about a quarter or more of disk space free | Retention cleanup and rebalancing need room |
| Use the same settings on all brokers unless there is a reason | Makes behavior predictable |
| Test upgrades under load | New versions can change performance in both directions |
| Document the ceiling and the date it was measured | People change; numbers get forgotten |
A well-run kitchen keeps a written capacity, trains for a busy night, keeps a spare cook on call, and checks equipment before a holiday. None of it is dramatic, and all of it is why service stays smooth.
Anti-Patterns to Avoid
Four popular mistakes and the better ways to work.
What people do
They quote a “Kafka can do a million messages per second” number from a blog post and size their cluster on it.
Why it hurts
That number came from a different message size, replication factor, hardware, and security setup. Your real ceiling may be a tenth of it, and you find out during a busy day.
Better approach
Measure with your own messages and settings, and calculate the limits from your own hardware.
What people do
They add brokers whenever things are slow, without finding out what is saturated.
Why it hurts
If the problem is tiny batches, a hot partition, or a quota, more brokers change nothing. The bill goes up while the problem stays.
Better approach
Follow the decision tree, find the saturated resource, and change that first.
What people do
They run production near 90 percent of the measured ceiling to save money.
Why it hurts
Any failure, restart, spike, or rebalance pushes the system past the knee, and latency and retries spiral.
Better approach
Plan normal load around 60 to 70 percent of the ceiling with one broker down.
What people do
They turn off replication or lower acknowledgments to win a benchmark.
Why it hurts
The benchmark looks great, but the production system, with its real safety needs, cannot reach that number, and a broker failure loses data.
Better approach
Benchmark with the same safety settings you will use in production.
Troubleshooting Playbook
From symptom to likely cause to first check.
| Symptom | Likely cause | First thing to check |
|---|---|---|
| Producers time out, brokers look calm | Producer-side limit, tiny batches, or a quota | Producer batch size, buffer use, and throttle time |
| Producer send calls block | Buffer memory full because batches leave too slowly | Request latency to brokers and buffer size |
| One broker much busier than others | Leader skew or a hot partition | Leaders per broker and bytes per partition |
| Latency jumps at the same load level every time | You have reached the knee of a resource | Thread idle percentages, disk, and network use |
| Fine at first, then drops after minutes | Cloud burst credits used up | Provider’s baseline network and disk figures |
| Under-replicated partitions rise with load | Followers cannot keep up | Follower fetch threads, disk, network of the lagging broker |
| High processor use on brokers with no traffic growth | Compression conversion, TLS, or format conversion | Compression settings and client versions |
| Reads suddenly slow for everyone | A lagging consumer flushed the page cache | Which consumer is far behind, and disk reads |
| Throughput capped at a round number | A quota or a purchased limit | Quota settings and disk or network purchase |
| Adding brokers changed nothing | Partitions were not moved to them | Where leaders and replicas currently live |
Always ask first: what changed recently? New client versions, a new consumer group, more partitions, a security change, or a traffic launch are the usual culprits.
Real-World and Industry Examples
The same reasoning appears wherever Kafka runs at scale.
Large social and professional networks
Companies that created or heavily use Kafka run very large clusters where each broker’s disk and network are watched closely, and balancing tools keep load even. Capacity planning includes the fan-out of many consumer groups reading the same activity data.
Payments and banking
Payment platforms usually favor strong safety settings and three copies across zones, accepting lower peak throughput. They plan around the reduced ceiling with a zone lost, and keep latency limits strict.
Ride-hailing and delivery platforms
Location updates are small, frequent messages. These platforms rely on batching and compression to keep request counts manageable, and use separate topics or clusters for real-time and bulk data.
Online retail during sales events
Traffic can jump many times above normal. Teams load-test weeks earlier, add capacity ahead of time, and freeze risky changes during the event.
Log and telemetry pipelines
Huge volumes of small text messages compress very well. These pipelines depend on compression and large batches to reach high throughput at reasonable cost, and often use tiered storage for history.
Managed Kafka services
Cloud-managed offerings publish per-unit throughput limits and enforce them through quotas. Understanding those limits is the same ceiling analysis, performed by the provider on your behalf.
A Day in the Life: ClickWave Analytics
Everything you learned, told as one small story.
ClickWave collects website click events from customers’ sites into a Kafka cluster of six brokers, with three copies of everything. Traffic has grown, and the team wants to know how much more it can take.
The complaint
Every evening producers report timeouts, though brokers show only moderate processor use. Someone suggests adding brokers.
The first look
The team checks the decision tree. Producer machines are not busy. Broker I/O threads are only 40 percent idle in the evening, which is on the edge. Disks are at 55 percent of the purchased speed.
The clue
Average batch size is 2 kilobytes while the setting allows 16. Linger time is zero. The producers send 200,000 small requests per second.
The change
They set a linger time of 10 milliseconds, raise the batch size, and turn on light compression. Batches grow to about 120 kilobytes.
The result
Requests per second fall by nearly two orders of magnitude, I/O threads sit 85 percent idle, and network traffic falls by half thanks to compression. Timeouts disappear.
The proper ceiling test
Using real click data, they step the load up. The knee arrives when disk writes reach the purchased speed at about 620 megabytes per second, well above the evening peak of 240.
The failure test
With one broker stopped, the ceiling drops to about 520. The team decides normal peaks should stay below 350, and sets a warning at that level.
The plan
Growth is 6 percent a month, so 350 is reached in about nine months. The team schedules the disk upgrade for month six, and writes the numbers in the runbook.
Adding brokers would have cost a lot and fixed nothing. A two-line settings change solved the problem, and the ceiling analysis turned a panic into a calendar entry.
Glossary: Every Term in One Place
A quick reference for the words used in this guide.
| Term | Simple meaning |
|---|---|
| Throughput | How much data or how many messages flow per second |
| Ceiling | The highest steady throughput before quality gets worse |
| Bottleneck | The single resource that limits the whole system |
| Saturation | A resource being busy all the time with no idle moments |
| Latency | The time one message or request takes |
| Knee | The load level at which latency begins to rise sharply |
| Headroom | The gap between current load and the ceiling |
| Batch | A group of messages sent in one unit |
| Linger time | How long a producer waits to fill a batch |
| Compression | Making data smaller, at the price of some processor work |
| Acknowledgment | The producer’s wait for confirmation of a write |
| Replication factor | The number of copies of each partition |
| In-sync replica | A copy that is fully caught up with the leader |
| Amplification | Extra work caused by copying and fan-out |
| Fan-out | Many readers each receiving the same data |
| Page cache | Operating system memory holding recently used file data |
| Zero-copy | Sending data from cache to network without passing through the application |
| Sequential write | Writing data one after the other along the end of a file |
| Network thread | Broker thread that reads requests and sends responses |
| I/O thread | Broker thread that does the actual request work |
| Purgatory | Holding area for requests that must wait for a condition |
| Quota | A deliberate limit on a client’s data rate or processor share |
| Skew | Uneven spread of load across partitions or brokers |
| Retry storm | Timeouts causing retries, which cause more load and more timeouts |
| Tiered storage | Keeping older data on cheaper remote storage |
Frequently Asked Questions
Quick answers to the questions beginners ask most often.
Summary and Key Takeaways
The whole story in a few short lines.
Key Takeaways
- The weakest link rules: the ceiling is set by the first resource to saturate: producer, broker threads, network, disk, or replication.
- Replication multiplies work: with three copies, disk writes and network traffic are several times the producer data, so compute each limit and take the smallest.
- Batching and compression are the biggest producer levers: fuller batches and lighter data raise the ceiling on every later step.
- Look inside the broker: thread idle percentages and request time by stage show whether the limit is queueing, disk, followers, or network.
- Averages hide skew: the busiest broker or partition sets the real ceiling, so watch per-broker and per-partition numbers.
- Test honestly: use real messages, production safety and security settings, long runs, and a failure test, and report latency at the knee.
- Plan for failure and growth: keep normal load around 60 to 70 percent of the reduced ceiling with one broker missing, alert on headroom, and track the trend.