This version is still in development and is not considered stable yet. For the latest stable version, please use Korvet 0.12.5!

Consumer: Commit Offsets

This page describes how Korvet handles Kafka OffsetCommitRequest operations.

This page is implementation-oriented and focuses on Kafka-to-Redis mapping details.

Consumer Commits Offset

Kafka Wire Protocol

OffsetCommitRequest (API Key: 8)
OffsetCommitRequest {
  group_id: "my-group"
  generation_id: 1           // from JoinGroup response
  member_id: "consumer-1-uuid"
  group_instance_id: null
  retention_time_ms: -1      // -1 = use broker default
  topics: [
    {
      name: "orders"
      partitions: [
        {
          partition: 0
          committed_offset: 44      // next offset to read
          committed_leader_epoch: -1
          committed_metadata: "processed batch 123"
        }
      ]
    }
  ]
}
OffsetCommitResponse (API Key: 8)
OffsetCommitResponse {
  throttle_time_ms: 0
  topics: [
    {
      name: "orders"
      partitions: [
        {
          partition: 0
          error_code: 0          // NONE
        }
      ]
    }
  ]
}

Sequence Diagram

OffsetCommitRequest Sequence

Redis Commands Detail

Offset commits have two storage effects in the current implementation:

  1. the broker acknowledges previously delivered Redis Stream entries with XACK

  2. the broker persists the committed Kafka offset in the committed-offset store keyed by (groupId, streamKey)

Implementation Notes

  • Offset Semantics: Kafka commits the next offset to read. The broker acknowledges every tracked delivered Redis message whose encoded offset is strictly less than the committed offset.

  • Tracked Delivery State: Delivered Redis message IDs are tracked in broker memory per (groupId, memberId, topic, partition) so commit can batch acknowledgments efficiently.

  • Committed Offset Persistence: OffsetFetch reads the committed-offset store first, so successful commits are not represented solely by Redis consumer-group metadata.

  • Batch / Retry Behavior: The handler first tries batched acknowledgments and falls back to per-partition retries if needed.