{"id":1148,"date":"2026-08-19T02:07:43","date_gmt":"2026-08-19T02:07:43","guid":{"rendered":"https:\/\/www.devopsschool.com\/tutorials\/?p=1148"},"modified":"2026-08-19T02:07:44","modified_gmt":"2026-08-19T02:07:44","slug":"kafka-master-tutorials-series-5-deep-dive-into-kafka-producers","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/tutorials\/kafka-master-tutorials-series-5-deep-dive-into-kafka-producers\/","title":{"rendered":"Kafka Master Tutorials Series: 5 &#8211; Deep Dive Into Kafka Producers"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">From&nbsp;<code>send()<\/code>&nbsp;to Broker ACK: Keys, Partitions, Batching, Retries, Reliability, Latency and Performance Tuning<\/h2>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Audience:<\/strong>&nbsp;Students and freshers with no prior Kafka experience<br><strong>Goal:<\/strong>&nbsp;Build from producer fundamentals to production-grade Kafka producer design and tuning<br><strong>Training environment:<\/strong>&nbsp;Confluent Kafka Cluster<\/p>\n<\/blockquote>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/file+.vscode-resource.vscode-cdn.net\/Users\/rajeshkumar\/Downloads\/Kafka_Producer_Deep_Dive.png\" alt=\"Kafka Producers \u2014 Complete Deep Dive\"\/><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">1. Learning Objectives<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">By the end of this tutorial, you should understand:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>What a Kafka Producer is<\/li>\n\n\n\n<li>What a Kafka record contains<\/li>\n\n\n\n<li>Key vs value<\/li>\n\n\n\n<li>Which record fields are optional<\/li>\n\n\n\n<li>How a producer discovers Kafka brokers<\/li>\n\n\n\n<li>How a producer selects a topic partition<\/li>\n\n\n\n<li>What happens when a key is present<\/li>\n\n\n\n<li>What happens when a key is absent<\/li>\n\n\n\n<li>Why &#8220;round robin&#8221; is not a complete description of modern default no-key partitioning<\/li>\n\n\n\n<li>What batching does<\/li>\n\n\n\n<li>What\u00a0<code>batch.size<\/code>\u00a0does<\/li>\n\n\n\n<li>What\u00a0<code>linger.ms<\/code>\u00a0does<\/li>\n\n\n\n<li>What compression does<\/li>\n\n\n\n<li>How producer memory is used<\/li>\n\n\n\n<li>What retries do<\/li>\n\n\n\n<li>Why idempotence matters<\/li>\n\n\n\n<li>What\u00a0<code>acks=0<\/code>,\u00a0<code>acks=1<\/code>, and\u00a0<code>acks=all<\/code>\u00a0mean<\/li>\n\n\n\n<li>How replicas and ISR affect producer reliability<\/li>\n\n\n\n<li>Who assigns Kafka offsets<\/li>\n\n\n\n<li>What\u00a0<code>flush()<\/code>\u00a0does<\/li>\n\n\n\n<li>How to optimize a producer for throughput<\/li>\n\n\n\n<li>How to optimize a producer for low latency<\/li>\n\n\n\n<li>How to build for production reliability<\/li>\n\n\n\n<li>Which producer metrics should be monitored<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">2. What Is a Kafka Producer?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A&nbsp;<strong>Kafka Producer<\/strong>&nbsp;is a client application that publishes records to Kafka topics.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The simplest mental model is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Application\n    |\n    v\nKafka Producer\n    |\n    v\nKafka Topic\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Vehicle\n   |\n   v\nTelematics Service\n   |\n   v\nKafka Producer\n   |\n   v\nTopic: vehicle-telemetry\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The producer does much more than simply &#8220;send a message.&#8221;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inside the producer, Kafka may need to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Create a record\n    |\n    v\nSerialize it\n    |\n    v\nObtain cluster metadata\n    |\n    v\nSelect a partition\n    |\n    v\nPlace it in memory\n    |\n    v\nBuild a batch\n    |\n    v\nCompress the batch\n    |\n    v\nLocate the partition leader\n    |\n    v\nSend the Produce request\n    |\n    v\nHandle acknowledgement\n    |\n    v\nRetry if required\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Kafka producers are designed to work asynchronously. In normal usage, your application calls&nbsp;<code>send()<\/code>, the record enters the producer pipeline, and a background I\/O process sends data to Kafka efficiently.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This asynchronous behavior is one of the main reasons Kafka producers can achieve high throughput.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">3. Kafka Producer Record<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A producer sends a&nbsp;<strong>record<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A simplified producer record contains:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Producer Record\n\nTopic       required\nPartition   optional\nTimestamp   optional\nKey         optional\nValue       usually the business payload\nHeaders     optional\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example business data:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"vehicle_id\": \"CAR-101\",\n  \"speed\": 88,\n  \"battery\": 72\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We might publish it as:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Topic = vehicle-telemetry\nKey   = CAR-101\nValue = {\"speed\":88,\"battery\":72}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you do not explicitly provide a partition, the producer&#8217;s partitioning logic decides where the record should go.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">4. Key and Value<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">These are two of the most important producer concepts.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4.1 Value<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<strong>value<\/strong>&nbsp;usually contains the business information.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"speed\": 88,\n  \"battery\": 72\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Think:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>VALUE\n=\n\"What happened?\"\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">4.2 Key<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<strong>key<\/strong>&nbsp;is commonly used to identify the entity that the event belongs to.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Key = CAR-101\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Think:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>KEY\n=\n\"Who or what does this event belong to?\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Examples:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Vehicle telemetry\nKey = vehicle_id\n\nCustomer events\nKey = customer_id\n\nOrder events\nKey = order_id\n\nBank account events\nKey = account_id\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The key is much more important than simply giving a message an ID.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The key commonly influences&nbsp;<strong>which partition receives the record<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">5. Why the Key Is So Important<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose we have:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Topic: vehicle-telemetry\n\nPartition 0\nPartition 1\nPartition 2\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The producer sends:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Key = CAR-101\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Kafka&#8217;s partitioning logic may determine:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CAR-101\n   |\n   v\nPartition 2\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Future records using the same key normally map consistently according to the same partitioning strategy:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CAR-101 speed=50  -&gt; P2\nCAR-101 speed=60  -&gt; P2\nCAR-101 speed=75  -&gt; P2\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Why does this matter?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Because Kafka ordering is fundamentally&nbsp;<strong>ordering inside a partition<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If all events for&nbsp;<code>CAR-101<\/code>&nbsp;go to the same partition, Kafka can preserve the order in which those records are appended to that partition.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">6. Key Design Is an Architecture Decision<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Imagine an order system:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>OrderCreated\nOrderPaid\nOrderPacked\nOrderShipped\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Key = order_id\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">then all events for one order can remain together:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ORDER-500\n\nOrderCreated\n     |\n     v\nOrderPaid\n     |\n     v\nOrderPacked\n     |\n     v\nOrderShipped\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">But a poor key can create a&nbsp;<strong>hot partition<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Imagine:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Key = country\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">and 70% of your traffic uses:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>India\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Your partition distribution might look like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Partition 0    ########################\nPartition 1    ###\nPartition 2    ##\nPartition 3    ##\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">One partition becomes extremely busy while others are lightly used.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This can overload:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>the partition leader<\/li>\n\n\n\n<li>the broker hosting that leader<\/li>\n\n\n\n<li>the consumers assigned to that partition<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">A good key must consider both:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Ordering requirements\n\nAND\n\nTraffic distribution\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">7. What If the Key Is Missing?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A common simplified explanation is:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">&#8220;If there is no key, Kafka uses round robin.&#8221;<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">That is not a complete description of modern producer behavior.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Modern Kafka producer implementations can use sticky\/adaptive behavior for records without keys so that records can remain on a partition long enough to create efficient batches.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A better beginner mental model is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>WITH KEY\n\nkey\n |\n v\npartitioning logic\n |\n v\nconsistent partition choice\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">versus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>WITHOUT KEY\n\nproducer selects an available partition\n        |\n        v\ntries to build efficient batches\n        |\n        v\nmoves to another partition over time\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Do not assume that every individual no-key record automatically rotates:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>P0 -&gt; P1 -&gt; P2 -&gt; P0 -&gt; P1 -&gt; P2\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A strict round-robin partitioner can be configured explicitly, but it is not the best universal description of modern default behavior.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">8. Can We Explicitly Select a Partition?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Yes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An application can explicitly specify a partition.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Topic     = orders\nPartition = 2\nKey       = ORDER-101\nValue     = ...\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then the producer does not need to choose the partition automatically.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But be careful.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Manual partition selection means your application becomes responsible for understanding:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Partition count\nBroker distribution\nLoad balancing\nOrdering\nScaling\nFuture partition changes\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In many applications, a better design is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>good key strategy\n+\nKafka partitioning\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">rather than hardcoding partition numbers.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">9. Topic, Partition and Broker Relationship<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Students must understand this before producer tuning.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Topic: vehicle-telemetry\n\nPartitions:\nP0\nP1\nP2\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Kafka may distribute the partition leaders like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Broker 1\n  P0 Leader\n\nBroker 2\n  P1 Leader\n\nBroker 3\n  P2 Leader\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the producer selects:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Partition 2\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">it must eventually send the record to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>P2 Leader\n=\nBroker 3\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">So the flow is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Producer\n   |\n   v\nTopic\n   |\n   v\nPartition selection\n   |\n   v\nPartition Leader\n   |\n   v\nBroker\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The producer does&nbsp;<strong>not<\/strong>&nbsp;randomly select any broker for the final write.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">10. How Does the Producer Know Which Broker Is the Leader?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">The producer uses&nbsp;<strong>cluster metadata<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It starts with one or more bootstrap endpoints.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Conceptually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Producer Configuration\n\nbootstrap.servers\n       |\n       v\nInitial Kafka connection\n       |\n       v\nCluster metadata\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Metadata tells the producer things such as:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Topic: orders\n\nP0 Leader = Broker 1\nP1 Leader = Broker 3\nP2 Leader = Broker 2\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Important:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>bootstrap server\n!=\nbroker that permanently receives every record\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Bootstrap servers are entry points that allow the client to discover the cluster.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">After discovery, the producer communicates with the correct partition leaders.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">11. Serialization<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Before Kafka can send your key and value over the network, they must be converted into bytes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Application Object\n      |\n      v\nSerializer\n      |\n      v\nBytes\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Both the key and value can have serializers.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>key.serializer=org.apache.kafka.common.serialization.StringSerializer\nvalue.serializer=org.apache.kafka.common.serialization.StringSerializer\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">With Confluent environments, you may later use schema-aware serializers for:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Avro\nProtobuf\nJSON Schema\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Schema Registry is a separate major Kafka\/Confluent topic that we will cover later.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">12. The Producer&#8217;s Internal Memory<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A simplified producer pipeline looks like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Application Thread\n       |\n       v\n     send()\n       |\n       v\nSerialization\n       |\n       v\nPartition Selection\n       |\n       v\nProducer Buffer \/ Accumulator\n       |\n       v\nRecord Batches\n       |\n       v\nBackground Sender \/ I\/O\n       |\n       v\nKafka Broker\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The producer has memory used to buffer records that have not yet been transmitted.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A key producer setting is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>buffer.memory\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This controls approximately how much memory is available to buffer records waiting to be sent.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">13. Why Buffer Records in Memory?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Imagine sending 100,000 events.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inefficient design:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Record 1 -&gt; Network request\nRecord 2 -&gt; Network request\nRecord 3 -&gt; Network request\n...\nRecord 100000 -&gt; Network request\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Huge overhead.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Kafka instead tries to do:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Record 1\nRecord 2\nRecord 3\nRecord 4\nRecord 5\n    |\n    v\nBatch\n    |\n    v\nEfficient Produce request\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Batching is one of Kafka producer&#8217;s most important performance mechanisms.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">14. Batching Happens Per Partition<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">This is critical.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose the producer is sending records to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>P0\nP1\nP2\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The producer builds batches for destination partitions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Conceptually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Producer Memory\n\nP0 Batch\n&#91;A]&#91;B]&#91;C]&#91;D]\n\nP1 Batch\n&#91;E]&#91;F]\n\nP2 Batch\n&#91;G]&#91;H]&#91;I]\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A broker request can then contain batches for partitions led by that broker.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is why&nbsp;<strong>partition selection and batching are connected<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">15.&nbsp;<code>batch.size<\/code><\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><code>batch.size<\/code>&nbsp;controls the target\/default producer batch size in bytes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A conceptual example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>batch.size = 16 KB\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Records:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>2 KB\n2 KB\n3 KB\n4 KB\n3 KB\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">can accumulate into a larger batch.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Larger useful batches may improve:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Network efficiency\nRequest efficiency\nCompression efficiency\nThroughput\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">But blindly setting a huge batch size is not automatically better.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Possible disadvantages:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Higher memory requirements\nMore unused batch allocation\nPotential additional waiting in some workloads\nNo benefit for very low traffic\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Always load-test.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">16.&nbsp;<code>linger.ms<\/code><\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">What if the batch is not full yet?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Should Kafka:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>send immediately?\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">or:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>wait briefly for more records?\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That is where:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>linger.ms\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">comes in.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>linger.ms = 5\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">means the producer may allow a very small batching window rather than immediately sending every under-filled batch.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">17.&nbsp;<code>batch.size<\/code>&nbsp;and&nbsp;<code>linger.ms<\/code>&nbsp;Work Together<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Think of a bus.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>batch.size\n=\nHow much can the bus carry?\n<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>linger.ms\n=\nHow long may the bus wait for more passengers?\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Simplified:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Records arrive\n     |\n     v\nAccumulator\n     |\n     +---- batch ready? ----&gt; SEND\n     |\n     +---- linger expires? -&gt; SEND\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is one of the most important producer performance relationships.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">18. Compression<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Kafka can compress record batches.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Common options include:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>none\ngzip\nsnappy\nlz4\nzstd\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Conceptually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Uncompressed Batch\n\n###########################\n\n        |\n        v\n\nCompression\n\n        |\n        v\n\n##########\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Potential benefits:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Less network traffic\nLess broker storage\nHigher effective throughput\nLower network cost\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Potential cost:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CPU used to compress and decompress\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">19. Which Compression Type Should We Use?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Do not memorize:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"X is always best.\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">There is no universal winner.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Evaluate:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Compression ratio\nCPU cost\nLatency\nRecord characteristics\nProducer language\/client\nBroker workload\nNetwork cost\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A production engineer benchmarks the real workload.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example, repeated JSON field names can often compress well.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">20. Producer Sends a Produce Request<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose our key maps to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Topic     = vehicle-telemetry\nPartition = 2\nLeader    = Broker 3\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Producer\n   |\n   v\nProduceRequest\n   |\n   v\nBroker 3\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The partition leader receives the batch and appends the records to the partition log.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">21. Who Assigns the Offset?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Another common misunderstanding:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The producer does&nbsp;<strong>not normally choose the Kafka offset<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose the partition currently contains:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Partition 2\n\nOffset 100\nOffset 101\nOffset 102\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The leader appends the new record:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Offset 103\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The producer can later receive metadata containing:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>topic\npartition\noffset\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">So:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Producer chooses\/supplies:\ntopic\nkey\/value\npossibly partition\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">while:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Kafka partition leader determines:\nrecord's log position \/ offset\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">22. Replicas<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Replication Factor = 3\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Partition 2 may look like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Broker 3 -&gt; Leader\nBroker 1 -&gt; Follower\nBroker 2 -&gt; Follower\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The producer writes to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Leader\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Followers replicate the leader&#8217;s data.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The producer does&nbsp;<strong>not<\/strong>&nbsp;normally send three separate copies directly to all replicas.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Think:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Producer\n   |\n   v\nLeader\n   |------&gt; Follower\n   |\n   +------&gt; Follower\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">23. Acknowledgements \u2014&nbsp;<code>acks<\/code><\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">One of the most important producer reliability settings is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>acks\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It controls when the producer considers the Produce request successfully acknowledged.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The major values are:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>acks=0\nacks=1\nacks=all\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">24.&nbsp;<code>acks=0<\/code>&nbsp;\u2014 Fire and Forget<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">The correct phrase is:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>fire and forget<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Flow:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Producer\n   |\n   v\nSend\n   |\n   v\nDoes not wait for broker acknowledgement\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Conceptually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Producer:\n\"I sent it. I am not waiting to know whether Kafka accepted it.\"\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Advantage<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Very little acknowledgement overhead.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Major disadvantage<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The producer does not receive broker acknowledgement that the broker successfully accepted the record.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Use only where message loss is acceptable.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">25.&nbsp;<code>acks=1<\/code>&nbsp;\u2014 Leader Acknowledges<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Flow:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Producer\n   |\n   v\nLeader Broker\n   |\n   v\nLeader accepts\/appends\n   |\n   v\nACK\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Followers may still be catching up.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Possible failure:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Leader writes record\n      |\n      v\nACK sent\n      |\n      v\nLeader fails before a follower has safely replicated\n      |\n      v\nPossible record loss\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">So&nbsp;<code>acks=1<\/code>&nbsp;is stronger than&nbsp;<code>acks=0<\/code>, but weaker than&nbsp;<code>acks=all<\/code>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">26.&nbsp;<code>acks=all<\/code>&nbsp;\u2014 Strongest Producer ACK Mode<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A common oversimplification is:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">&#8220;<code>acks=all<\/code>&nbsp;means fully replicated to every configured replica.&#8221;<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">A more accurate explanation is:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">The partition leader waits for the acknowledgement conditions involving the current in-sync replicas.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">This makes&nbsp;<code>acks=all<\/code>&nbsp;the strongest normal producer acknowledgement mode.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, it must be understood together with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Replication Factor\nISR\nmin.insync.replicas\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">27.&nbsp;<code>min.insync.replicas<\/code><\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Now combine:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Replication Factor\n+\nISR\n+\nacks\n+\nmin.insync.replicas\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A common production-style example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>replication.factor = 3\nmin.insync.replicas = 2\nacks = all\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Healthy state:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Leader    - ISR\nFollower  - ISR\nFollower  - ISR\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">One broker fails:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Leader    - ISR\nFollower  - ISR\nFollower  - unavailable\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">There may still be enough in-sync replicas to satisfy the configured minimum.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But if:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ISR size &lt; min.insync.replicas\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Kafka can reject strongly acknowledged writes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That is not necessarily a bad thing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Production principle:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Sometimes failing a write\nis safer than\naccepting a write with weaker durability.\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">28. Reliability vs Latency<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">You can now see a major tradeoff.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Conceptually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>acks=0\n\nLess waiting\n|\nv\nLower acknowledgement latency\n|\nv\nWeaker reliability feedback\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">versus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>acks=all\n\nStronger acknowledgement conditions\n|\nv\nStronger durability\n|\nv\nPotentially more acknowledgement latency\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Actual latency also depends on:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Network\nBroker load\nBatching\nCompression\nPartition leadership\nReplica health\nRequest queues\nQuotas\nCluster capacity\nApplication workload\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Never tune only one setting in isolation.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">29. Retries<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Networks fail.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Brokers restart.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Partition leaders change.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Connections break temporarily.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Therefore Kafka producers can retry eligible transient failures.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Conceptually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Send\n |\n v\nTemporary failure\n |\n v\nRetry\n |\n v\nSuccess\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">But retries create an important question.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">30. The Duplicate Problem<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Imagine:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Producer sends Record A\n        |\n        v\nBroker stores A\n        |\n        v\nACK is lost on the network\n        |\n        v\nProducer thinks:\n\"Maybe it failed.\"\n        |\n        v\nProducer retries A\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Without protection:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>A\nA\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">could appear.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is why idempotence is important.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">31. Idempotent Producer<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Kafka&#8217;s idempotent producer protects against duplicate writes caused by producer retries within Kafka&#8217;s producer guarantees.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Conceptually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Send A\n  |\n  v\nBroker stores A\n  |\n  v\nACK lost\n  |\n  v\nRetry A\n  |\n  v\nKafka identifies retry\n  |\n  v\nDo not create another logical copy\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Important:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Idempotent Producer\n!=\nAutomatically exactly-once business processing\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Exactly-once behavior involving multiple Kafka writes, consumed offsets, transactions, external databases or other business side effects is a larger topic.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We will cover Kafka Transactions separately.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">32.&nbsp;<code>max.in.flight.requests.per.connection<\/code><\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A producer can have multiple requests waiting for responses.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Conceptually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Request 1 ----------------&gt;\nRequest 2 ----------------&gt;\nRequest 3 ----------------&gt;\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This improves throughput.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But historically, retries plus multiple in-flight requests could create ordering concerns when idempotence was disabled.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Therefore these concepts must be understood together:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Throughput\nRetries\nOrdering\nIdempotence\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">33.&nbsp;<code>delivery.timeout.ms<\/code><\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Instead of thinking only:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"How many times should I retry?\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">a better mental model is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"How long may this record continue trying before delivery is considered failed?\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That is the role of:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>delivery.timeout.ms\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It bounds the overall delivery attempt window.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This can include:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>time waiting before send\nbroker acknowledgement waiting\neligible retries\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">34. Producer Memory and Backpressure<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose the application produces:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>1,000,000 records\/sec\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">but Kafka can currently accept:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>300,000 records\/sec\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Records accumulate in producer memory.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Application\n   |||||||||||\n   vvvvvvvvvvv\nProducer Buffer\n########################\n   |||\n   vvv\nKafka\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Eventually the producer buffer may become full.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The application can then experience blocking and eventually send failures depending on configuration.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is&nbsp;<strong>backpressure<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Do not &#8220;solve&#8221; it by blindly adding huge memory.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ask:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Why is Kafka slower than the producer?\n\nBroker saturation?\nNetwork?\nQuota?\nHot partition?\nToo few partitions?\nBroker failover?\nLarge records?\nInsufficient cluster capacity?\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">35.&nbsp;<code>buffer.memory<\/code><\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><code>buffer.memory<\/code>&nbsp;controls approximately how much producer memory is available for pending records.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Increasing it can help absorb short bursts.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But it does not create infinite throughput.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If your steady-state application rate is greater than Kafka&#8217;s sustainable rate:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>more buffer\n=\nfailure happens later\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">not:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>problem solved\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">36.&nbsp;<code>max.block.ms<\/code><\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><code>send()<\/code>&nbsp;is normally asynchronous, but application calls can still block in some cases, such as:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>waiting for metadata\nwaiting for producer buffer space\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>max.block.ms<\/code>&nbsp;limits how long the producer may block in these situations.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This matters for application responsiveness.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Web request\n   |\n   v\nproducer.send()\n   |\n   v\nbuffer completely exhausted\n   |\n   v\napplication thread waits\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Kafka producer performance can therefore affect your API latency even before the send ultimately succeeds or fails.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">37.&nbsp;<code>send()<\/code>&nbsp;Does Not Mean &#8220;Already Stored&#8221;<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">This distinction is critical.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Application code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>producer.send(record);\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">does&nbsp;<strong>not<\/strong>&nbsp;automatically mean:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"The record is already safely stored in Kafka.\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It normally means that the record has entered the producer&#8217;s asynchronous delivery pipeline.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To observe the delivery result, use:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Future\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">or:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Callback\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">38. Use Callbacks in Real Applications<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Conceptually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>producer.send(record, (metadata, exception) -&gt; {\n    if (exception != null) {\n        <em>\/\/ handle\/report failure<\/em>\n    } else {\n        <em>\/\/ success<\/em>\n        <em>\/\/ metadata.topic()<\/em>\n        <em>\/\/ metadata.partition()<\/em>\n        <em>\/\/ metadata.offset()<\/em>\n    }\n});\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This provides visibility into:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Success\nFailure\nTopic\nPartition\nOffset\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Do not produce important events and completely ignore asynchronous failures.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">39.&nbsp;<code>flush()<\/code><\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><code>flush()<\/code>&nbsp;means:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Force currently buffered records to be made available for immediate sending and wait for their associated requests to complete.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Conceptually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Producer Buffer\n\nA\nB\nC\nD\n   |\n   v\nflush()\n   |\n   v\nsend pending records now\n   |\n   v\nwait for requests to complete\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">40. Should We Call&nbsp;<code>flush()<\/code>&nbsp;After Every Record?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Normally:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>No.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Bad high-throughput pattern:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>send(A)\nflush()\n\nsend(B)\nflush()\n\nsend(C)\nflush()\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This destroys much of the benefit of:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>asynchronous sending\nbatching\nrequest aggregation\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You effectively move toward:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>send\nwait\n\nsend\nwait\n\nsend\nwait\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Use&nbsp;<code>flush()<\/code>&nbsp;intentionally.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Typical uses:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>controlled synchronization point\nsmall teaching\/demo application\nbefore a critical application boundary\nbefore shutdown when needed\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">41.&nbsp;<code>flush()<\/code>&nbsp;vs&nbsp;<code>close()<\/code><\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">They are not the same.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><code>flush()<\/code><\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>send pending buffered records\nwait for requests\nproducer remains usable\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><code>close()<\/code><\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>complete producer shutdown\nrelease resources\nbackground I\/O stops\nproducer should no longer be used\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A Kafka producer owns:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>memory buffers\nnetwork connections\nbackground I\/O resources\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Always close it properly.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">42. Complete Producer Journey<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Put everything together:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>APPLICATION\n    |\n    v\nCreate business event\n    |\n    v\nProducerRecord\n    |\n    +--&gt; Topic\n    +--&gt; Key\n    +--&gt; Value\n    +--&gt; Headers\n    +--&gt; Optional partition\/timestamp\n    |\n    v\nSerializer\n    |\n    v\nCluster Metadata\n    |\n    v\nPartition Selection\n    |\n    v\nProducer Buffer\n    |\n    v\nPer-Partition Batch\n    |\n    +--&gt; batch.size\n    +--&gt; linger.ms\n    |\n    v\nCompression\n    |\n    v\nBackground Sender\n    |\n    v\nNetwork\n    |\n    v\nPartition Leader Broker\n    |\n    v\nAppend to Partition Log\n    |\n    v\nOffset Assigned\n    |\n    v\nFollower Replication\n    |\n    v\nISR\n    |\n    v\nacks condition\n    |\n    v\nACK \/ Error\n    |\n    v\nRetry if eligible\n    |\n    v\nCallback \/ Future\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is the producer lifecycle you should be able to explain in an interview and in a production incident.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">43. Producer Performance Tuning \u2014 The Correct Approach<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Do not start tuning like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Increase batch.size!\nIncrease memory!\nDecrease acks!\nAdd partitions!\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Instead:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>1. Define requirement\n2. Measure baseline\n3. Find bottleneck\n4. Change one variable\n5. Load test\n6. Measure again\n7. Check reliability impact\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Performance tuning without measurements is guessing.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">44. Goal 1 \u2014 Optimize for High Throughput<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">If your goal is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Maximum events\/sec\nMaximum MB\/sec\nEfficient broker\/network usage\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">consider:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Increase useful batching\n     |\n     v\nappropriate batch.size\n\nAllow batches to fill\n     |\n     v\nappropriate linger.ms\n\nReduce bytes transferred\n     |\n     v\ncompression\n\nDistribute traffic\n     |\n     v\nenough well-balanced partitions\n\nAvoid per-message blocking\n     |\n     v\nasynchronous sends\n\nHandle bursts\n     |\n     v\nappropriate producer memory\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Also monitor:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>broker throttling\nhot partitions\nrequest latency\nerror rate\nretry rate\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">45. High-Throughput Mental Model<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Less efficient:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>A -&gt; Kafka\nB -&gt; Kafka\nC -&gt; Kafka\nD -&gt; Kafka\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">More efficient:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>A\nB\nC\nD\nE\nF\n |\n v\nBatch\n |\n v\nCompress\n |\n v\nKafka\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Kafka achieves much of its producer efficiency by moving batches rather than treating every record as an isolated network transaction.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">46. Goal 2 \u2014 Minimize Latency<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose the requirement is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Event must reach Kafka as quickly as practical.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Consider:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Smaller batching wait\nLower linger.ms\nAvoid unnecessary application blocking\nHealthy nearby Kafka infrastructure\nCorrect partition distribution\nLow broker load\nFast serialization\nAppropriate compression choice\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">But do not automatically set every batching value to zero.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Under real load, a tiny batching window may improve overall system efficiency enough to produce excellent practical latency.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Always benchmark your real workload.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">47. Goal 3 \u2014 Maximum Reliability<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">For events where loss is unacceptable, think about the complete chain:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Producer\n   |\n   v\nacks=all\n   |\n   v\nHealthy ISR\n   |\n   v\nAppropriate min.insync.replicas\n   |\n   v\nReplication factor\n   |\n   v\nIdempotence\n   |\n   v\nRetries\n   |\n   v\nError handling\n   |\n   v\nMonitoring\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A common production-oriented pattern is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Replication Factor = 3\nmin.insync.replicas = 2\nacks = all\nenable.idempotence = true\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is a useful starting concept, not a universal configuration that should be copied blindly.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">48. The Throughput \/ Latency \/ Reliability Triangle<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A Kafka producer balances:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>               THROUGHPUT\n                  \/\\\n                 \/  \\\n                \/    \\\n               \/      \\\n              \/        \\\n        LATENCY ------ RELIABILITY\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Examples:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>More batching\n-&gt; often better throughput\n-&gt; may add waiting time\n\nMore compression\n-&gt; less network\/storage\n-&gt; more CPU\n\nacks=all\n-&gt; stronger durability\n-&gt; stronger acknowledgement conditions\n\nacks=0\n-&gt; less acknowledgement waiting\n-&gt; much weaker delivery feedback\n\nMore producer memory\n-&gt; more burst absorption\n-&gt; does not increase broker capacity\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Master-level Kafka is about understanding these tradeoffs.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">49. Important Producer Tuning Parameters<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Parameter<\/th><th class=\"has-text-align-left\" data-align=\"left\">Main purpose<\/th><th class=\"has-text-align-left\" data-align=\"left\">Main tradeoff<\/th><\/tr><\/thead><tbody><tr><td><code>batch.size<\/code><\/td><td>Build larger record batches<\/td><td>Memory \/ workload dependent<\/td><\/tr><tr><td><code>linger.ms<\/code><\/td><td>Give batches time to fill<\/td><td>Throughput vs added waiting<\/td><\/tr><tr><td><code>compression.type<\/code><\/td><td>Reduce bytes<\/td><td>CPU vs network\/storage<\/td><\/tr><tr><td><code>acks<\/code><\/td><td>Delivery acknowledgement strength<\/td><td>Reliability vs ACK latency<\/td><\/tr><tr><td><code>enable.idempotence<\/code><\/td><td>Prevent duplicate retry writes<\/td><td>Requires compatible reliability settings<\/td><\/tr><tr><td><code>retries<\/code><\/td><td>Recover from transient failures<\/td><td>Longer time before permanent failure<\/td><\/tr><tr><td><code>delivery.timeout.ms<\/code><\/td><td>Bound delivery attempts<\/td><td>Reliability window vs failure speed<\/td><\/tr><tr><td><code>buffer.memory<\/code><\/td><td>Buffer pending records<\/td><td>Memory usage<\/td><\/tr><tr><td><code>max.block.ms<\/code><\/td><td>Limit blocking on metadata\/buffer<\/td><td>Application responsiveness<\/td><\/tr><tr><td><code>max.in.flight.requests.per.connection<\/code><\/td><td>Parallel outstanding requests<\/td><td>Throughput\/order interaction<\/td><\/tr><tr><td><code>max.request.size<\/code><\/td><td>Limit producer request size<\/td><td>Large-message constraints<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Do not tune these independently without understanding their interactions.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">50. Example Balanced Producer Profile<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">For teaching purposes, a balanced producer might start conceptually with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>acks=all\nenable.idempotence=true\n\ncompression.type=zstd\n\nlinger.ms=5\nbatch.size=65536\n\ndelivery.timeout.ms=120000\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is an&nbsp;<strong>example starting profile<\/strong>, not a production recipe.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The correct configuration depends on:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>event size\nevent rate\nlatency SLO\ncluster location\nnumber of partitions\nnetwork bandwidth\nCPU\ncompression ratio\nbroker capacity\nfailure requirements\nclient library\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">51. Confluent Kafka Cluster Connection<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">For Confluent Cloud-style training, the producer also needs security and connection settings.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Conceptually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>bootstrap.servers=&lt;CONFLUENT_BOOTSTRAP_SERVER&gt;\n\nsecurity.protocol=SASL_SSL\nsasl.mechanism=PLAIN\n\nsasl.jaas.config=&lt;API_KEY_AND_SECRET&gt;\n\nkey.serializer=...\nvalue.serializer=...\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Keep secrets outside application source code wherever possible.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">After authentication, the normal producer flow remains:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Discover metadata\n      |\n      v\nSelect partition\n      |\n      v\nFind partition leader\n      |\n      v\nProduce batch\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">52. Practical Java Example<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Simplified teaching example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Properties props = new Properties();\n\nprops.put(\"bootstrap.servers\", \"&lt;BOOTSTRAP_SERVER&gt;\");\nprops.put(\"security.protocol\", \"SASL_SSL\");\nprops.put(\"sasl.mechanism\", \"PLAIN\");\n\nprops.put(\n    \"key.serializer\",\n    \"org.apache.kafka.common.serialization.StringSerializer\"\n);\n\nprops.put(\n    \"value.serializer\",\n    \"org.apache.kafka.common.serialization.StringSerializer\"\n);\n\nprops.put(\"acks\", \"all\");\nprops.put(\"enable.idempotence\", \"true\");\nprops.put(\"compression.type\", \"zstd\");\nprops.put(\"linger.ms\", \"5\");\n\nKafkaProducer&lt;String, String&gt; producer =\n    new KafkaProducer&lt;&gt;(props);\n\nProducerRecord&lt;String, String&gt; record =\n    new ProducerRecord&lt;&gt;(\n        \"vehicle-telemetry\",\n        \"CAR-101\",\n        \"{\\\"speed\\\":88}\"\n    );\n\nproducer.send(record, (metadata, exception) -&gt; {\n\n    if (exception != null) {\n        exception.printStackTrace();\n        return;\n    }\n\n    System.out.println(\n        \"topic=\" + metadata.topic()\n        + \" partition=\" + metadata.partition()\n        + \" offset=\" + metadata.offset()\n    );\n});\n\nproducer.flush();\nproducer.close();\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Why call&nbsp;<code>flush()<\/code>&nbsp;here?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Because this is a small teaching program and we want an explicit point at which all pending sends have completed before shutdown.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In a high-throughput long-running service, do not call&nbsp;<code>flush()<\/code>&nbsp;after every record.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">53. Lab 1 \u2014 Keyed Events<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Create a topic with multiple partitions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vehicle-telemetry\n\nP0\nP1\nP2\nP3\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Produce:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CAR-101 event 1\nCAR-101 event 2\nCAR-101 event 3\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Use the callback to print:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>partition\noffset\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Observe whether records for the same key consistently go to the same partition.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then try:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CAR-101\nCAR-102\nCAR-103\nCAR-104\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Compare the partition distribution.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">54. Lab 2 \u2014 No-Key Events<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Produce records without a key:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>null -&gt; event 1\nnull -&gt; event 2\nnull -&gt; event 3\n...\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Print the assigned partitions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Do not assume that modern no-key behavior is a naive strict per-record round robin.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Observe how batches and partition selection interact.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">55. Lab 3 \u2014 Batching Experiment<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Run a load test with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>linger.ms = 0\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Record:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>throughput\nrequest rate\nlatency\naverage batch size\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then test:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>linger.ms = 5\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>linger.ms = 20\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Do not ask only:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"Which value is best?\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Ask:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"What changed and why?\"\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">56. Lab 4 \u2014 Compression Experiment<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Produce the same data using:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>compression.type=none\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">then:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>compression.type=lz4\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">then:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>compression.type=zstd\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Measure:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>producer CPU\nbytes sent\nthroughput\nlatency\ncompression ratio\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The correct choice depends on your workload.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">57. Lab 5 \u2014&nbsp;<code>acks<\/code>&nbsp;Experiment<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">In a safe training cluster, compare:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>acks=0\nacks=1\nacks=all\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Do not only measure speed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Record:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Producer latency\nErrors\nBehavior during broker\/leader disruption\nDurability guarantees\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The objective is to understand that configuration is about&nbsp;<strong>failure behavior<\/strong>, not only benchmark numbers.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">58. Lab 6 \u2014&nbsp;<code>flush()<\/code>&nbsp;Experiment<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Test:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>for each event:\n    send()\n    flush()\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then compare with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>send many events asynchronously\nflush once at the end\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Compare throughput and latency.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This demonstrates why excessive&nbsp;<code>flush()<\/code>&nbsp;calls can remove much of the benefit of producer batching.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">59. Producer Metrics to Monitor<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A production producer should never be a black box.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Important metrics include:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>record-send-rate\nrecord-error-rate\nrecord-retry-rate\nrequest-latency-avg\nrequest-latency-max\nbatch-size-avg\nrecords-per-request-avg\ncompression-rate-avg\nrecord-queue-time-avg\nbuffer-available-bytes\nwaiting-threads\nrequests-in-flight\nproduce-throttle-time-avg\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">These help you understand whether the producer is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>healthy\nslow\nbuffer-constrained\nretrying\nthrottled\npoorly batched\nexperiencing broker\/network latency\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">60. How to Read Producer Metrics<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">High&nbsp;<code>record-error-rate<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Investigate:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>authentication\nauthorization\nbroker availability\ninvalid records\nmessage size\nISR health\ntimeouts\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">High&nbsp;<code>record-retry-rate<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Possible causes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>network instability\nleader elections\nbroker overload\ntransient broker errors\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">High&nbsp;<code>request-latency-avg<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Possible causes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>network latency\nbroker overload\nreplication delay\nthrottling\ncross-region traffic\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Very low&nbsp;<code>batch-size-avg<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Possible interpretation:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>batches are not filling\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Possible reasons:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>low traffic\nvery low linger\ntoo many destination partitions for the traffic level\napplication send pattern\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Low&nbsp;<code>buffer-available-bytes<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Producer buffer pressure is increasing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ask:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Is the application producing events\nfaster than Kafka can accept them?\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">61. Producer Troubleshooting Flow<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">When producers become slow:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>START\n  |\n  v\nAre sends failing?\n  |\n  v\nCheck error and retry metrics\n  |\n  v\nCheck request latency\n  |\n  v\nCheck broker throttling\n  |\n  v\nCheck partition distribution\n  |\n  v\nCheck hot partitions\n  |\n  v\nCheck batch efficiency\n  |\n  v\nCheck compression\n  |\n  v\nCheck producer buffer pressure\n  |\n  v\nCheck network latency\n  |\n  v\nCheck broker \/ ISR health\n  |\n  v\nChange one thing\n  |\n  v\nLoad test again\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Do not change ten settings simultaneously.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Otherwise, you will not know which change helped or hurt.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">62. Common Producer Mistakes<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Mistake 1 \u2014 No meaningful key<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Later the team says:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"We need strict ordering for each customer.\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Key design should be considered early.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Mistake 2 \u2014 Bad low-cardinality key<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Examples:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>country\nregion\nevent_type\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">may create very uneven traffic.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Mistake 3 \u2014 Calling&nbsp;<code>flush()<\/code>&nbsp;for every event<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This destroys useful asynchronous batching.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Mistake 4 \u2014 Assuming&nbsp;<code>send()<\/code>&nbsp;means successful durable write<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">It does not.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Observe callback\/Future results.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Mistake 5 \u2014 Using&nbsp;<code>acks=0<\/code>&nbsp;for critical business events<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You lose normal broker acknowledgement of delivery.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Mistake 6 \u2014 Setting huge buffers to hide slow Kafka<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This delays the symptom rather than fixing sustainable throughput.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Mistake 7 \u2014 Increasing partitions without thinking about keys<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You can still have hot partitions.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Mistake 8 \u2014 Enabling retries without understanding idempotence<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Retry semantics matter.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Mistake 9 \u2014 Optimizing throughput while ignoring reliability<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A benchmark that loses critical records under failure is not a successful production design.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Mistake 10 \u2014 Copying configuration blindly<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Always benchmark your workload and understand your client version.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">63. Production Producer Checklist<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Before calling a producer production-ready, verify:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>[ ] Correct topic selected<\/li>\n\n\n\n<li>[ ] Key strategy intentionally designed<\/li>\n\n\n\n<li>[ ] Partition distribution tested<\/li>\n\n\n\n<li>[ ] Serialization format selected<\/li>\n\n\n\n<li>[ ] Schema evolution strategy defined where required<\/li>\n\n\n\n<li>[ ]\u00a0<code>acks<\/code>\u00a0intentionally selected<\/li>\n\n\n\n<li>[ ] Replication \/ ISR policy understood<\/li>\n\n\n\n<li>[ ] Idempotence behavior understood<\/li>\n\n\n\n<li>[ ] Retry behavior tested<\/li>\n\n\n\n<li>[ ] Delivery timeout understood<\/li>\n\n\n\n<li>[ ] Batching load-tested<\/li>\n\n\n\n<li>[ ]\u00a0<code>linger.ms<\/code>\u00a0load-tested<\/li>\n\n\n\n<li>[ ]\u00a0<code>batch.size<\/code>\u00a0load-tested<\/li>\n\n\n\n<li>[ ] Compression benchmarked<\/li>\n\n\n\n<li>[ ] Producer memory monitored<\/li>\n\n\n\n<li>[ ] Backpressure behavior tested<\/li>\n\n\n\n<li>[ ] Callback\/errors handled<\/li>\n\n\n\n<li>[ ] Producer properly closed on shutdown<\/li>\n\n\n\n<li>[ ]\u00a0<code>flush()<\/code>\u00a0used only where appropriate<\/li>\n\n\n\n<li>[ ] Hot partitions monitored<\/li>\n\n\n\n<li>[ ] Producer latency monitored<\/li>\n\n\n\n<li>[ ] Error and retry rates monitored<\/li>\n\n\n\n<li>[ ] Failure testing performed<\/li>\n\n\n\n<li>[ ] Broker failure tested<\/li>\n\n\n\n<li>[ ] Network interruption tested<\/li>\n\n\n\n<li>[ ] Application SLOs documented<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">64. Interview-Level Questions<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">What is a Kafka producer?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A Kafka client that publishes records to Kafka topics.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What does a producer record contain?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A topic, key\/value and optionally headers, timestamp and an explicitly selected partition.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Is the key mandatory?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">No. But a key is extremely important when partition affinity and per-entity ordering matter.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Does no key always mean strict round robin?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">No. Modern producers can use sticky\/adaptive behavior to improve batching. Strict round robin can be explicitly configured.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Who assigns the offset?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The Kafka partition leader assigns the log position when the record is appended.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Does the producer write directly to every replica?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">No. The producer writes to the partition leader. Followers replicate from the leader.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What is&nbsp;<code>batch.size<\/code>?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A producer setting that influences the target\/default amount of data grouped into a partition batch.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What is&nbsp;<code>linger.ms<\/code>?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A small upper waiting window that gives batches time to fill before being sent.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What does&nbsp;<code>acks=0<\/code>&nbsp;mean?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The producer does not wait for broker acknowledgement.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What does&nbsp;<code>acks=1<\/code>&nbsp;mean?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The partition leader acknowledges without waiting for the strongest ISR acknowledgement condition.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What does&nbsp;<code>acks=all<\/code>&nbsp;mean?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The leader waits for the current in-sync replica acknowledgement requirements. This is Kafka&#8217;s strongest normal producer acknowledgement mode.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why use idempotence?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To prevent duplicate Kafka writes caused by retries within producer idempotence guarantees.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What does&nbsp;<code>flush()<\/code>&nbsp;do?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">It forces currently buffered records to become immediately eligible for sending and waits for their associated requests to complete.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">65. Master Mental Model<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A beginner thinks:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Producer sends a message to Kafka.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A Kafka engineer thinks:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Business Event\n     |\n     v\nProducerRecord\n     |\n     v\nKey + Value + Headers\n     |\n     v\nSerialization\n     |\n     v\nMetadata\n     |\n     v\nPartition Strategy\n     |\n     v\nProducer Buffer\n     |\n     v\nPer-Partition Batch\n     |\n     +--&gt; batch.size\n     +--&gt; linger.ms\n     |\n     v\nCompression\n     |\n     v\nBackground Sender\n     |\n     v\nPartition Leader\n     |\n     v\nBroker Append\n     |\n     v\nOffset Assignment\n     |\n     v\nReplication\n     |\n     v\nISR\n     |\n     v\nacks\n     |\n     v\nRetry \/ Idempotence\n     |\n     v\nDelivery Result\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A production Kafka engineer asks:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>How does every step affect:\n\nPERFORMANCE?\nLATENCY?\nRELIABILITY?\nAVAILABILITY?\nCOST?\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That is the level of thinking we want from the Kafka Master Tutorials series.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">66. Final Takeaways<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Remember these ten ideas:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>A producer is much more than a network sender.<\/li>\n\n\n\n<li>Keys are fundamental to partitioning and ordering design.<\/li>\n\n\n\n<li>Modern no-key partitioning should not simply be taught as strict round robin.<\/li>\n\n\n\n<li>Kafka batches records primarily for efficiency.<\/li>\n\n\n\n<li><code>batch.size<\/code>\u00a0and\u00a0<code>linger.ms<\/code>\u00a0work together.<\/li>\n\n\n\n<li>Compression trades CPU for potentially lower network and storage usage.<\/li>\n\n\n\n<li>The producer writes to the\u00a0<strong>partition leader<\/strong>, not directly to every replica.<\/li>\n\n\n\n<li><code>acks<\/code>, ISR and\u00a0<code>min.insync.replicas<\/code>\u00a0work together to define durability.<\/li>\n\n\n\n<li>Retries should be understood together with idempotence and delivery timeout.<\/li>\n\n\n\n<li>Producer performance tuning must be driven by measurements, not copied configuration.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">67. Suggested Next Producer Tutorials<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">After this producer foundation, the natural deep dives are:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Producer Internals\n        |\n        v\nPartitioning Strategies\n        |\n        v\nProducer Reliability &amp; Delivery Semantics\n        |\n        v\nProducer Performance Tuning Lab\n        |\n        v\nProducer Errors, Retries &amp; Idempotence\n        |\n        v\nKafka Transactions\n        |\n        v\nProduction Producer Monitoring\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That path takes students from producer fundamentals to production-grade producer mastery.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>From&nbsp;send()&nbsp;to Broker ACK: Keys, Partitions, Batching, Retries, Reliability, Latency and Performance Tuning Audience:&nbsp;Students and freshers with no prior Kafka experienceGoal:&nbsp;Build from producer fundamentals to production-grade Kafka producer&#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1148","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1148","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/comments?post=1148"}],"version-history":[{"count":1,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1148\/revisions"}],"predecessor-version":[{"id":1149,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1148\/revisions\/1149"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/media?parent=1148"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/categories?post=1148"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/tags?post=1148"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}