Understanding Kafka Consumer Lag

2 min read

If you run event-driven systems, consumer lag is your heartbeat. It tells you whether the consumers are keeping up with reality — and it usually warns you before your users notice anything.

What consumer lag actually measures

Lag is the difference between the end offset of a partition and the current commit offset of the consumer group. In plain terms: how many messages are waiting to be processed.

  • A small, oscillating lag is normal — it means consumers breathe with traffic.
  • A lag that only grows is a system falling behind.
  • A lag that jumps to a wall is a consumer that stopped.

How to check it

The classic tool is the consumer groups CLI:

kafka-consumer-groups \
  --bootstrap-server localhost:9092 \
  --describe \
  --group orders-service

The columns that matter:

TOPIC           PARTITION  CURRENT-OFFSET  LOG-END-OFFSET  LAG
orders.events   0          143210          143210          0
orders.events   1          129880          143905          14025
orders.events   2          131004          131004          0

Partition 1 is behind by 14,025 messages. Whether that is an incident depends on your traffic — which is why lag belongs next to your normal metrics, not just in a CLI.

A mental model

The topic is the buffer. Consumers pull at their own pace. Lag is the buffer depth each consumer still owes.

Common causes and fixes

SymptomLikely causeFirst move
Lag grows on all partitionsThroughput exceeded capacityScale consumers (up to partition count), then rethink processing
Lag grows on one partitionHot key / skewCheck partitioning key; isolate or re-key hot entities
Lag spikes, then drainsBurst traffic or batch jobVerify it drains; alert on trend, not on absolute value
Lag frozen at a numberConsumer stopped (crashed, blocked)Check liveness, look for poison-pill message
Lag resets to zero suddenlyOffsets reset or consumer skippedTreat as an incident — data may be lost or reprocessed

Alert on the trend, not the number

A threshold like "lag > 10,000" means nothing without context. Better:

  1. Rate of change — is lag growing over N minutes?
  2. Time to drain — lag divided by recent processing rate.
  3. Per-partition maximum, not the average — averages hide skew.

Idempotency is the real safety net

When consumers fall behind, you will eventually restart, replay, or rescale them — which means messages get processed more than once. Design processing to be idempotent from day one. Then lag becomes an operational metric, not a correctness crisis.

Summary

  • Consumer lag is the distance between now and processed.
  • Read it per partition, alert on trend and time-to-drain.
  • Most lag incidents are capacity, skew, or a stopped consumer — in that order.
  • Idempotent consumers make lag a non-event.