LimePoint Engineering··4 min read

Kafka Producer Best Practices: Enabling Reliable Data Streaming

Introduction

In Kafka ecosystems, producers serve as critical components for publishing data to topics. These systems ensure efficient and dependable delivery to brokers and consuming applications. A properly configured producer maintains data integrity, minimizes latency, and enables scalability -- essential qualities for any streaming architecture.

Neglecting best practices leads to data loss, inefficient resource usage, and operational difficulties. This guide explores key producer configuration strategies.

Optimize Batch Size

Batching allows producers to send multiple messages efficiently rather than individually, though finding the right balance between batch size and latency matters. Related configurations include batch.size and linger.ms.

When immediate message dispatch takes priority over throughput, set linger.ms to 0 (the default). For high-throughput scenarios, enable batching by setting linger.ms to a positive value with a reasonable batch.size. Experiment with combinations and monitor statistics to discover optimal settings for your use case.

Acknowledgments

Kafka supports three acknowledgment modes via the acks parameter:

  • all: Strongest guarantee; ensures safe replication across in-sync replicas
  • 1: Balanced approach between performance and reliability
  • 0: Weakest guarantee; offers low latency but risks data loss

When using acks=all, configure min.insync.replicas appropriately. For example, with a replication factor of 3, set min.insync.replicas to 2 to ensure all means all in-sync replicas, not all existing replicas.

Compression

Enabling compression reduces network transmission and broker storage while consuming minimal CPU resources. Effectiveness increases when combined with batching.

Configure compression at the producer, broker, or topic level (disabled by default). Best practices include:

Do:

  1. Leave topic compression.type at its default (producer)
  2. Specify compression.type in the producer

Avoid:

  1. Different compression algorithms across layers -- creates unnecessary broker decompression/recompression
  2. Unspecified producer compression while setting topic-level codecs

Compression Algorithm Comparison

TypeRatioCPU UsageSpeedBandwidth
GzipHighestHighestSlowestLowest
SnappyMediumModerateModerateMedium
Lz4LowLowestFastestHighest
ZstdMediumModerateModerateMedium

Verify integration with intended consumers after enabling compression, especially in heterogeneous environments.

Error Handling

Implement robust error handling and retry logic to prevent data loss. Leverage the KafkaProducer callback mechanism to verify successful publishing:

producer.send(producerRecord, (recordMetadata, exception) -> {
    if (exception == null) {
        System.out.println("Record written to offset " +
                recordMetadata.offset() + " partition " +
                recordMetadata.partition());
    } else {
        System.err.println("An error occurred");
        exception.printStackTrace(System.err);
    }
});

The producer automatically retries retriable errors like NotEnoughReplicasException and TimeoutException. For non-retriable errors (e.g., RecordTooLargeException), implement application-level handling such as logging, alerting, or halting publication.

Throttling

Monitor producer performance and implement throttling to prevent broker overload using configurations like:

  • max.request.size
  • linger.ms
  • max.in.flight.requests.per.connection (set to 1 for sequential requests)

Alternatively, implement application-level rate limiting or broker-side client quotas.

Idempotence

Enable idempotence by setting enable.idempotence to true. This prevents message duplication during retries and guarantees message ordering. Using transactions automatically enables idempotence.

Transactions

Transactions enable atomic writes across multiple topics and partitions -- either all messages succeed or none do.

Use transactions when:

  1. Publishing multiple messages atomically across partitions/topics
  2. Consuming messages from source topics and committing offsets atomically

Example code:

Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("transactional.id", "my-transactional-id");
Producer<String, String> producer = new KafkaProducer<>(props,
    new StringSerializer(), new StringSerializer());

producer.initTransactions();

try {
    producer.beginTransaction();
    for (int i = 0; i < 100; i++) {
        producer.send(new ProducerRecord<>("my-topic",
            Integer.toString(i), Integer.toString(i)));
    }
    producer.commitTransaction();
} catch (ProducerFencedException | OutOfOrderSequenceException |
         AuthorizationException e) {
    producer.close();
} catch (KafkaException e) {
    producer.abortTransaction();
}
producer.close();

The transactional.id enables recovery across sessions and should derive from shard identifiers in partitioned applications.

Message Keys

Select meaningful keys -- they determine partition assignment and affect message ordering. Common choices include strings, JSON strings, and Avro.

  • String: Lightweight and simple, lacks structure
  • Avro: Supports structured data; requires Schema Registry dependency
  • JSON: Structured without mandatory Schema Registry, though field order affects byte sequences

When using producers in different languages, ensure consistent hashing algorithms across platforms -- different implementations may route identical keys to different partitions.

Monitoring and Metrics

Implement comprehensive monitoring using tools like Prometheus and Grafana with Kafka's built-in metrics. Relevant batch performance metrics include:

  • batch-size-avg
  • records-per-request-avg
  • record-queue-time-avg
  • record-send-rate
  • record-size-avg
  • compression-rate-avg

Request-level metrics include request-rate, requests-in-flight, and request-latency-avg.

Testing

Conduct thorough testing across scenarios including high load, network failures, and broker outages.

Testing approaches:

  • Unit testing: Use MockProducer
  • Integration testing: Leverage EmbeddedKafka (SpringBoot) or Testcontainers
  • Benchmark testing: Use Kafka's kafka-producer-perf-test tool or Trogdor

Version Compatibility

Ensure producer version compatibility with broker versions. Confluent Platform users can reference compatibility tables in official documentation.

Security

Follow security best practices including SSL/TLS encryption and SASL authentication or mTLS. Leverage producer interceptors to enhance security of event data in transit and at rest.

Conclusion

Following these best practices creates robust, efficient data streaming pipelines. Properly configured producers ensure reliability, low latency, and efficient resource use -- making Kafka invaluable for real-time data processing.

As a Confluent Premier Partner, LimePoint offers guidance and expertise for organizations looking to advance their Kafka journey.

Ready to build what comes next?

Real-time data, governed APIs, secure identity. Tell us where you are and we'll show you what's possible.

Get in Touch