Scaling Kafka Consumers in Spring Boot: How We Cut Lag and Saved Latency
When scaling high-throughput event-driven microservices in fintech, default Spring Kafka consumer configurations often run into throughput limits under peak loads.
Here is the exact production setup we engineered to resolve consumer lag and reduce API processing latency by 35%.
1. Concurrency Tuning Over Single-Threaded Listeners
By default, @KafkaListener operates with concurrency = 1. When a partition receives high message volume, processing gets backlogged.
@Configuration
@EnableKafka
public class KafkaConsumerConfig {
@Bean
public ConcurrentKafkaListenerContainerFactory<String, PaymentEvent> kafkaListenerContainerFactory(
ConsumerFactory<String, PaymentEvent> consumerFactory) {
ConcurrentKafkaListenerContainerFactory<String, PaymentEvent> factory =
new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(consumerFactory);
factory.setConcurrency(6); // Matches number of partition splits
factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);
return factory;
}
}
2. Explicit Batch Processing and Idempotency
Instead of committing offset per message, processing batches with manual acknowledgments ensures atomic handling:
@Service
public class PaymentEventConsumer {
@KafkaListener(topics = "payment.settlement.v1", containerFactory = "kafkaListenerContainerFactory")
public void consume(ConsumerRecord<String, PaymentEvent> record, Acknowledgment ack) {
try {
processPayment(record.value());
ack.acknowledge();
} catch (Exception ex) {
log.error("Failed processing record key: {}", record.key(), ex);
// Route to Dead Letter Queue (DLQ)
handleDeadLetter(record);
ack.acknowledge();
}
}
}
3. Key Takeaway
Scaling Kafka consumer pipelines requires matching topic partition count with container concurrency, tuning database connection pools and implementing dead letter queues for failed messages.
What consumer concurrency patterns do you use in your production clusters? Drop your thoughts below!
Top comments (0)