Poor performance of log4j2 in combination with Kafka
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Apache Log4j2 is a popular logging library widely used in Java applications to provide logging functionality. Kafka is an open-source stream-processing software platform developed by the Apache Software Foundation, written in Scala and Java. While both technologies are powerful and widely adopted, there have been noted performance issues when Log4j2 is used in combination with Kafka, particularly in high-throughput environments. This article explores the reasons behind this poor performance and suggests possible optimizations.
Understanding the Integration
Log4j2 can be configured to send logs directly to a Kafka topic. This integration uses a Kafka appender within Log4j2, which allows logs to be published directly to a Kafka topic. While this setup eliminates the need for additional log aggregation tools, it introduces complexities in terms of thread handling, network I/O, and serialization.
Key Performance Issues
- Thread Context Switching and Synchronization: Log4j2’s asynchronous logging capabilities often leverage a single background thread to dispatch log messages to Kafka. In high-throughput scenarios, synchronization between application threads producing log messages and the dispatcher thread can become a bottleneck.
- Serialization Overhead: Each log message needs to be formatted and serialized into a format suitable for transmission over the network (typically into bytes). Serialization can be computationally expensive and can degrade performance when logging at high volumes.
- Network I/O: As log messages are sent over the network to a Kafka broker, there's an inherent latency and bandwidth overhead. This I/O overhead can significantly impact overall application performance, particularly if the Kafka cluster is remote or over-utilized.
- Kafka Client Performance: The performance of the Kafka client (producer) used by Log4j2 can also impact logging performance. Tuning the Kafka producer configuration is crucial to achieve optimal performance.
Technical Analysis and Examples
Consider an application with high log generation rate. Using Log4j2’s default synchronous logger configuration with the Kafka appender, the application's threads are blocked until the log messages are confirmed to be sent by Kafka. This synchronization significantly impacts application throughput.
Switching to an asynchronous configuration helps, but still the serialization and dispatch to Kafka are performed by a limited number of background threads managed by Log4j2. In high-demand scenarios, these threads can become the bottleneck.
Example configuration snippet in log4j2.xml:
Optimization Strategies
- Increase the number of background threads in Log4j2’s asynchronous logger to better handle higher volumes of log messages.
- Adjust Kafka producer settings such as
batch.size,linger.ms, andbuffer.memoryto batch messages more efficiently and reduce the number of network requests. - Compress log messages before sending them to Kafka to reduce the volume of data transmitted over the network.
- Use faster serialization libraries or custom serialization mechanisms that are optimized for log data.
- Monitor Kafka and application performance regularly to identify bottlenecks and adjust configurations accordingly.
Data Summary Table
| Issue | Impact | Possible Optimization |
| Thread Context Switching | High CPU usage | Increase dispatcher threads |
| Serialization Overhead | Increased latency | Use efficient serialization, compress data |
| Network I/O | Bandwidth limit | Batch log messages, adjust Kafka settings |
| Kafka Client Performance | Throughput impact | Tune producer configurations |
Additional Considerations
Beyond performance, ensure that the use of Kafka for logging complies with your data governance and security policies. Logs can contain sensitive information, and secure transmission and access controls must be in place.
In conclusion, while integrating Log4j2 with Kafka provides a scalable and flexible logging solution, attention must be paid to the configuration and tuning of both Log4j2 and Kafka to avoid significant performance degradation. By understanding and addressing the outlined key issues, developers can optimize the logging performance and maintain high application throughput.
Related reading
- Poor performance with Spark streaming, Kafka and multiple topics
- Porting Kafka's murmur2 implementation to Go
- PRECONDITION_FAILED Delivery Acknowledge Timeout on Celery & RabbitMQ with Gevent and concurrency
- Prevent Kafka broker from closing idle connection
- Position N circles of different radii inside a larger circle without overlapping
- Possible to get multiple object from Amazon S3 in single request?
- Possible reasons for timeout when trying to access EC2 instance
- Post parameter is always null

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.