Skip to content

AxonOps — AI-Native Control Plane for Open Source Data Platforms

Kafka Monitoring

Comprehensive monitoring guide for Apache Kafka clusters.


Kafka ClusterMetrics CollectionMonitoring StackBroker 1Broker 2Broker 3JMX ExporterMetrics StoreAlertingDashboardsJMXJMXJMX

MetricDescriptionAlert Threshold
kafka.controller:ActiveControllerCountActive controller count≠ 1
kafka.server:UnderReplicatedPartitionsUnder-replicated partitions> 0
kafka.controller:OfflinePartitionsCountOffline partitions> 0
kafka.server:UnderMinIsrPartitionCountBelow min ISR> 0
MetricDescriptionNotes
kafka.server:MessagesInPerSecMessages per secondPer broker/topic
kafka.server:BytesInPerSecBytes in per secondPer broker/topic
kafka.server:BytesOutPerSecBytes out per secondPer broker/topic
kafka.server:TotalProduceRequestsPerSecProduce requestsPer broker
kafka.server:TotalFetchRequestsPerSecFetch requestsPer broker
MetricDescriptionAlert Threshold
kafka.network:TotalTimeMs,request=ProduceProduce latencyP99 > 100ms
kafka.network:TotalTimeMs,request=FetchConsumerFetch latencyP99 > 100ms
kafka.network:RequestQueueTimeMsQueue time> 10ms
kafka.network:ResponseQueueTimeMsResponse queue time> 10ms
MetricDescriptionAlert Threshold
Consumer lagRecords behindGrowing continuously
Lag growth rateLag increase ratePositive for extended period

Terminal window
# Broker startup
export KAFKA_JMX_OPTS="-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.port=9999"
bin/kafka-server-start.sh config/server.properties
jmx-exporter.yml
lowercaseOutputName: true
lowercaseOutputLabelNames: true
rules:
# Broker metrics
- pattern: kafka.server<type=(.+), name=(.+), topic=(.+)><>Count
name: kafka_server_$1_$2_total
labels:
topic: "$3"
type: COUNTER
- pattern: kafka.server<type=(.+), name=(.+)><>Count
name: kafka_server_$1_$2_total
type: COUNTER
# Request metrics
- pattern: kafka.network<type=RequestMetrics, name=(.+), request=(.+)><>Count
name: kafka_network_request_$1_total
labels:
request: "$2"
type: COUNTER
- pattern: kafka.network<type=RequestMetrics, name=(.+)Percentile, request=(.+)><>(\d+)thPercentile
name: kafka_network_request_$1_percentile
labels:
request: "$2"
percentile: "$3"
type: GAUGE
# Controller metrics
- pattern: kafka.controller<type=(.+), name=(.+)><>Value
name: kafka_controller_$1_$2
type: GAUGE

AlertConditionAction
Offline PartitionsOfflinePartitionsCount > 0Investigate broker failures
No ControllerActiveControllerCount != 1Check controller election
Under Min ISRUnderMinIsrPartitionCount > 0Check broker health
AlertConditionAction
Under-ReplicatedUnderReplicatedPartitions > 0 for 5minCheck replication lag
High Produce LatencyP99 > 100msCheck disk I/O, network
Consumer Lag GrowingLag increasing continuouslyScale consumers
Disk Usage High> 80% usedAdd storage or adjust retention
alert-rules.yml
groups:
- name: kafka-critical
rules:
- alert: KafkaOfflinePartitions
expr: kafka_controller_offline_partitions_count > 0
for: 1m
labels:
severity: critical
annotations:
summary: "Kafka has offline partitions"
- alert: KafkaNoActiveController
expr: kafka_controller_active_controller_count != 1
for: 1m
labels:
severity: critical
annotations:
summary: "Kafka cluster has no active controller"
- alert: KafkaUnderReplicatedPartitions
expr: kafka_server_replica_manager_under_replicated_partitions > 0
for: 5m
labels:
severity: warning
annotations:
summary: "Kafka has under-replicated partitions"
- alert: KafkaConsumerLagGrowing
expr: rate(kafka_consumer_group_lag[5m]) > 0
for: 15m
labels:
severity: warning
annotations:
summary: "Consumer lag is continuously growing"

Terminal window
# Check lag for all groups
kafka-consumer-groups.sh --bootstrap-server kafka:9092 \
--describe --all-groups
# Check specific group
kafka-consumer-groups.sh --bootstrap-server kafka:9092 \
--describe --group my-consumer-group
GROUP TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG
my-group my-topic 0 1000 1050 50
my-group my-topic 1 2000 2000 0
my-group my-topic 2 1500 1600 100
ColumnDescription
CURRENT-OFFSETConsumer's committed offset
LOG-END-OFFSETLatest offset in partition
LAGLOG-END-OFFSET - CURRENT-OFFSET

PanelMetrics
Active Controllerkafka_controller_active_controller_count
Online BrokersCount of responding brokers
Offline Partitionskafka_controller_offline_partitions_count
Under-Replicatedkafka_server_replica_manager_under_replicated_partitions
PanelMetrics
Messages In/skafka_server_broker_topic_metrics_messages_in_total rate
Bytes In/skafka_server_broker_topic_metrics_bytes_in_total rate
Bytes Out/skafka_server_broker_topic_metrics_bytes_out_total rate
Requests/skafka_network_request_total rate
PanelMetrics
Produce P99kafka_network_request_total_time_ms{quantile="0.99"}
Fetch P99kafka_network_request_total_time_ms{quantile="0.99"}
Queue Timekafka_network_request_queue_time_ms
PanelMetrics
CPU UsageHost CPU metrics
Memory UsageHost memory metrics
Disk Usagekafka_log_size per partition
Network I/OHost network metrics

kafka-health-check.sh
#!/bin/bash
BOOTSTRAP_SERVER=${1:-"localhost:9092"}
echo "=== Kafka Health Check ==="
# Check broker connectivity
echo -n "Broker connectivity: "
if kafka-broker-api-versions.sh --bootstrap-server $BOOTSTRAP_SERVER > /dev/null 2>&1; then
echo "OK"
else
echo "FAILED"
exit 1
fi
# Check offline partitions
OFFLINE=$(kafka-topics.sh --bootstrap-server $BOOTSTRAP_SERVER \
--describe --unavailable-partitions 2>/dev/null | wc -l)
echo "Offline partitions: $OFFLINE"
if [ "$OFFLINE" -gt 0 ]; then
echo "CRITICAL: Offline partitions detected"
exit 2
fi
# Check under-replicated partitions
UNDER_REP=$(kafka-topics.sh --bootstrap-server $BOOTSTRAP_SERVER \
--describe --under-replicated-partitions 2>/dev/null | wc -l)
echo "Under-replicated partitions: $UNDER_REP"
if [ "$UNDER_REP" -gt 0 ]; then
echo "WARNING: Under-replicated partitions detected"
exit 1
fi
echo "=== All checks passed ==="
exit 0

MetricDescriptionAlert Threshold
kafka.server:type=ReplicaManager,name=IsrShrinksPerSecISR shrink rate> 0 during normal operation
kafka.server:type=ReplicaManager,name=IsrExpandsPerSecISR expansion rateShould follow shrinks
kafka.server:type=ReplicaManager,name=FailedIsrUpdatesPerSecFailed ISR update rate> 0
kafka.server:type=ReplicaManager,name=LeaderCountLeader replicas per brokerUneven distribution
kafka.server:type=ReplicaManager,name=PartitionCountPartitions per brokerUneven distribution
kafka.server:type=ReplicaManager,name=OfflineReplicaCountOffline replicas> 0
kafka.server:type=ReplicaFetcherManager,name=MaxLag,clientId=ReplicaMax follower lagProportional to batch size

MetricDescriptionNotes
kafka.network:type=RequestMetrics,name=TotalTimeMsTotal request timeSum of all phases
kafka.network:type=RequestMetrics,name=RequestQueueTimeMsTime waiting in request queueHigh values indicate overload
kafka.network:type=RequestMetrics,name=LocalTimeMsTime processing at leaderDisk I/O bound
kafka.network:type=RequestMetrics,name=RemoteTimeMsTime waiting for followersNon-zero with acks=all
kafka.network:type=RequestMetrics,name=ResponseQueueTimeMsTime in response queueNetwork thread saturation
kafka.network:type=RequestMetrics,name=ResponseSendTimeMsTime sending responseNetwork bandwidth
MetricDescriptionAlert Threshold
kafka.network:type=SocketServer,name=NetworkProcessorAvgIdlePercentNetwork thread idle ratio< 0.3
kafka.server:type=KafkaRequestHandlerPool,name=RequestHandlerAvgIdlePercentRequest handler idle ratio< 0.3
kafka.network:type=RequestChannel,name=RequestQueueSizePending requestsGrowing continuously

Purgatory holds requests waiting for conditions to be met (e.g., acks from replicas).

MetricDescriptionNotes
kafka.server:type=DelayedOperationPurgatory,name=PurgatorySize,delayedOperation=ProducePending produce requestsNon-zero with acks=-1
kafka.server:type=DelayedOperationPurgatory,name=PurgatorySize,delayedOperation=FetchPending fetch requestsDepends on fetch.wait.max.ms

MetricDescriptionNotes
kafka.log:type=LogFlushStats,name=LogFlushRateAndTimeMsLog flush rate and timeDisk performance indicator
kafka.log:type=LogManager,name=OfflineLogDirectoryCountOffline log directoriesShould be 0
kafka.log:type=Log,name=Size,topic=X,partition=YPartition size in bytesPer-partition storage
kafka.log:type=Log,name=NumLogSegments,topic=X,partition=YSegment count per partitionSegment management
kafka.log:type=Log,name=LogStartOffset,topic=X,partition=YFirst available offsetRetention tracking
kafka.log:type=Log,name=LogEndOffset,topic=X,partition=YLatest offsetProgress tracking

MetricDescriptionAlert Threshold
kafka.controller:type=ControllerStats,name=LeaderElectionRateAndTimeMsLeader election rateNon-zero during failures
kafka.controller:type=ControllerStats,name=UncleanLeaderElectionsPerSecUnclean elections> 0 (potential data loss)
kafka.controller:type=KafkaController,name=TopicsToDeleteCountPending topic deletionsShould decrease
kafka.controller:type=KafkaController,name=ReplicasToDeleteCountPending replica deletionsShould decrease
kafka.controller:type=ControllerEventManager,name=EventQueueSizeController event queueGrowing continuously
kafka.controller:type=ControllerEventManager,name=EventQueueTimeMsEvent wait timeHigh latency

KRaft clusters expose Raft consensus metrics on both controllers and brokers.

MetricDescriptionNotes
kafka.server:type=raft-metrics,name=current-stateNode stateleader, follower, candidate, observer
kafka.server:type=raft-metrics,name=current-leaderCurrent leader ID-1 indicates unknown
kafka.server:type=raft-metrics,name=current-epochCurrent quorum epochIncrements on elections
kafka.server:type=raft-metrics,name=high-watermarkCommitted log offset-1 if unknown
kafka.server:type=raft-metrics,name=log-end-offsetEnd of Raft logReplication progress
MetricDescriptionAlert Threshold
kafka.server:type=raft-metrics,name=commit-latency-avgAverage commit latencyIncreasing trend
kafka.server:type=raft-metrics,name=commit-latency-maxMaximum commit latencySpikes
kafka.server:type=raft-metrics,name=election-latency-avgAverage election timeExtended elections
kafka.server:type=raft-metrics,name=fetch-records-rateRecord fetch rateReplication throughput
kafka.server:type=raft-metrics,name=append-records-rateRecord append rateWrite throughput

The group coordinator manages consumer group membership and offset storage.

MetricDescriptionNotes
kafka.server:type=group-coordinator-metrics,name=num-partitions,state=loadingLoading partitionsShould be transient
kafka.server:type=group-coordinator-metrics,name=num-partitions,state=activeActive partitionsNormal operation
kafka.server:type=group-coordinator-metrics,name=num-partitions,state=failedFailed partitionsShould be 0
MetricDescriptionNotes
kafka.server:type=group-coordinator-metrics,name=consumer-group-count,state=stableStable groupsNormal state
kafka.server:type=group-coordinator-metrics,name=consumer-group-count,state=emptyEmpty groupsNo active members
kafka.server:type=group-coordinator-metrics,name=consumer-group-count,state=assigningGroups assigning partitionsRebalance in progress
kafka.server:type=group-coordinator-metrics,name=consumer-group-count,state=reconcilingGroups reconcilingIncremental rebalance
kafka.server:type=group-coordinator-metrics,name=consumer-group-rebalance-rateRebalance frequencyHigh rate indicates instability
MetricDescriptionNotes
kafka.server:type=group-coordinator-metrics,name=offset-commit-rateOffset commit rateConsumer activity
kafka.server:type=group-coordinator-metrics,name=offset-expiration-rateOffset expiration rateInactive consumers
kafka.server:type=GroupMetadataManager,name=NumOffsetsTotal committed offsetsStorage overhead
kafka.server:type=GroupMetadataManager,name=NumGroupsTotal consumer groupsGroup management

For clusters with tiered storage enabled, monitor remote storage operations.

MetricDescriptionNotes
kafka.server:type=BrokerTopicMetrics,name=RemoteFetchBytesPerSecBytes read from remoteCold read volume
kafka.server:type=BrokerTopicMetrics,name=RemoteFetchRequestsPerSecRemote fetch requestsCold read frequency
kafka.server:type=BrokerTopicMetrics,name=RemoteCopyBytesPerSecBytes copied to remoteUpload throughput
kafka.server:type=BrokerTopicMetrics,name=RemoteCopyRequestsPerSecCopy requests to remoteUpload frequency
kafka.server:type=BrokerTopicMetrics,name=RemoteDeleteRequestsPerSecDelete requestsRetention cleanup
MetricDescriptionAlert Threshold
kafka.server:type=BrokerTopicMetrics,name=RemoteCopyLagBytesBytes pending uploadGrowing continuously
kafka.server:type=BrokerTopicMetrics,name=RemoteCopyLagSegmentsSegments pending upload> configured threshold
kafka.server:type=BrokerTopicMetrics,name=RemoteDeleteLagBytesBytes pending deletionGrowing continuously
kafka.server:type=BrokerTopicMetrics,name=RemoteDeleteLagSegmentsSegments pending deletion> configured threshold
MetricDescriptionAlert Threshold
kafka.server:type=BrokerTopicMetrics,name=RemoteFetchErrorsPerSecRemote read errors> 0
kafka.server:type=BrokerTopicMetrics,name=RemoteCopyErrorsPerSecRemote write errors> 0
kafka.server:type=BrokerTopicMetrics,name=RemoteDeleteErrorsPerSecRemote delete errors> 0
MetricDescriptionAlert Threshold
org.apache.kafka.storage.internals.log:type=RemoteStorageThreadPool,name=RemoteLogReaderTaskQueueSizeRead task queueGrowing continuously
org.apache.kafka.storage.internals.log:type=RemoteStorageThreadPool,name=RemoteLogReaderAvgIdlePercentRead thread utilization< 0.3
kafka.log.remote:type=RemoteLogManager,name=RemoteLogManagerTasksAvgIdlePercentCopy thread utilization< 0.3

Client-side metrics for monitoring producer applications.

MetricDescriptionNotes
kafka.producer:type=producer-metrics,name=record-send-rateRecords sent per secondProduction rate
kafka.producer:type=producer-metrics,name=byte-rateBytes sent per secondBandwidth usage
kafka.producer:type=producer-metrics,name=compression-rate-avgCompression ratio< 1.0 indicates compression
kafka.producer:type=producer-metrics,name=record-size-avgAverage record sizeSizing validation
MetricDescriptionAlert Threshold
kafka.producer:type=producer-metrics,name=request-latency-avgAverage request latencyIncreasing trend
kafka.producer:type=producer-metrics,name=request-latency-maxMaximum request latencySpikes
kafka.producer:type=producer-metrics,name=record-queue-time-avgTime in bufferHigh indicates backpressure
kafka.producer:type=producer-metrics,name=produce-throttle-time-avgThrottle time> 0 indicates quota hit
MetricDescriptionAlert Threshold
kafka.producer:type=producer-metrics,name=buffer-available-bytesAvailable buffer spaceApproaching 0
kafka.producer:type=producer-metrics,name=buffer-total-bytesTotal buffer sizeConfiguration reference
kafka.producer:type=producer-metrics,name=bufferpool-wait-ratioTime waiting for buffer> 0 indicates memory pressure
kafka.producer:type=producer-metrics,name=batch-size-avgAverage batch sizeTuning indicator
MetricDescriptionAlert Threshold
kafka.producer:type=producer-metrics,name=record-error-rateRecord error rate> 0
kafka.producer:type=producer-metrics,name=record-retry-rateRecord retry rateHigh rate

Client-side metrics for monitoring consumer applications.

MetricDescriptionNotes
kafka.consumer:type=consumer-fetch-manager-metrics,name=records-consumed-rateRecords consumed per secondConsumption rate
kafka.consumer:type=consumer-fetch-manager-metrics,name=bytes-consumed-rateBytes consumed per secondBandwidth usage
kafka.consumer:type=consumer-fetch-manager-metrics,name=fetch-rateFetch request rateRequest frequency
kafka.consumer:type=consumer-fetch-manager-metrics,name=records-per-request-avgRecords per fetchEfficiency indicator
MetricDescriptionAlert Threshold
kafka.consumer:type=consumer-fetch-manager-metrics,name=records-lag-maxMaximum partition lagGrowing continuously
kafka.consumer:type=consumer-fetch-manager-metrics,name=records-lag,partition=XPer-partition lagAbove threshold
kafka.consumer:type=consumer-fetch-manager-metrics,name=records-lead-minMinimum lead (distance to start)Approaching 0
MetricDescriptionAlert Threshold
kafka.consumer:type=consumer-coordinator-metrics,name=rebalance-totalTotal rebalancesHigh count
kafka.consumer:type=consumer-coordinator-metrics,name=rebalance-rate-per-hourRebalance frequency> 1-2 per hour
kafka.consumer:type=consumer-coordinator-metrics,name=rebalance-latency-avgAverage rebalance time> configured session timeout
kafka.consumer:type=consumer-coordinator-metrics,name=assigned-partitionsAssigned partition countUneven distribution
MetricDescriptionAlert Threshold
kafka.consumer:type=consumer-coordinator-metrics,name=heartbeat-rateHeartbeats per secondBelow expected rate
kafka.consumer:type=consumer-coordinator-metrics,name=heartbeat-response-time-maxMax heartbeat response timeApproaching session timeout
kafka.consumer:type=consumer-coordinator-metrics,name=last-heartbeat-seconds-agoTime since last heartbeatApproaching session timeout
MetricDescriptionNotes
kafka.consumer:type=consumer-coordinator-metrics,name=commit-rateCommit rateCommit frequency
kafka.consumer:type=consumer-coordinator-metrics,name=commit-latency-avgAverage commit latencyPerformance indicator

For Kafka Streams applications, monitor stream processing performance.

MetricDescriptionNotes
kafka.streams:type=stream-thread-metrics,name=stateThread stateRUNNING, PARTITIONS_ASSIGNED, etc.
kafka.streams:type=stream-thread-metrics,name=commit-rateCommits per secondProcessing frequency
kafka.streams:type=stream-thread-metrics,name=poll-ratePolls per secondInput rate
kafka.streams:type=stream-thread-metrics,name=process-rateRecords processed per secondProcessing throughput
MetricDescriptionAlert Threshold
kafka.streams:type=stream-thread-metrics,name=process-latency-avgAverage processing timeIncreasing trend
kafka.streams:type=stream-thread-metrics,name=commit-latency-avgAverage commit timeHigh latency
kafka.streams:type=stream-thread-metrics,name=poll-latency-avgAverage poll timeHigh latency
kafka.streams:type=stream-thread-metrics,name=punctuate-latency-avgAverage punctuate timeHigh latency
MetricDescriptionNotes
kafka.streams:type=stream-thread-metrics,name=task-created-rateTask creation rateRebalance activity
kafka.streams:type=stream-thread-metrics,name=task-closed-rateTask close rateRebalance activity
kafka.streams:type=stream-task-metrics,name=process-ratePer-task processing rateTask-level throughput
kafka.streams:type=stream-task-metrics,name=dropped-records-rateDropped record rateData loss indicator
MetricDescriptionNotes
kafka.streams:type=stream-state-metrics,name=put-rateState store write rateWrite throughput
kafka.streams:type=stream-state-metrics,name=get-rateState store read rateRead throughput
kafka.streams:type=stream-state-metrics,name=flush-rateState store flush ratePersistence frequency
kafka.streams:type=stream-state-metrics,name=restore-rateState restoration rateRecovery progress

Monitor client quota enforcement.

MetricDescriptionNotes
kafka.server:type=Produce,user=X,client-id=Y,name=throttle-timeProducer throttle time> 0 indicates quota exceeded
kafka.server:type=Fetch,user=X,client-id=Y,name=throttle-timeConsumer throttle time> 0 indicates quota exceeded
kafka.server:type=Request,user=X,client-id=Y,name=throttle-timeRequest throttle time> 0 indicates quota exceeded

Monitor authentication and authorization.

MetricDescriptionAlert Threshold
kafka.server:type=socket-server-metrics,name=successful-authentication-rateSuccessful auth rateReference baseline
kafka.server:type=socket-server-metrics,name=failed-authentication-rateFailed auth rate> 0
kafka.network:type=SocketServer,name=ExpiredConnectionsKilledCountConnections killed (auth expiry)> 0 with re-auth enabled

Metric Naming Convention (KIP-1100)

Kafka 4.2 corrects metric names to follow the kafka.COMPONENT naming convention. Some metric names from earlier versions have been renamed. Monitor for any dashboard or alerting rule breakage after upgrading.

MetricKIPDescription
kafka.controller:AvgIdleRatioKIP-1190Controller thread idle ratio. Low values indicate the controller is under heavy load
kafka.server:AvgIdleRatio (MetadataLoader)KIP-1229MetadataLoader thread idle ratio. Monitors metadata processing capacity
kafka.server:RequestHandlerAvgIdlePercentKIP-1207Fixed in KRaft combined mode to report accurately (previously incorrect in combined controller+broker nodes)
Feature level metricsKIP-1180Generic metrics for finalized and supported feature levels across the cluster
client-id tag on AppInfoKIP-1120AppInfo metrics now include a client-id tag for distinguishing between client instances
application-id tag on Streams stateKIP-1221Kafka Streams client state metric now includes an application-id tag
Share partition lagKIP-1226Lag metrics for share group partition consumption progress