- [Feature] Add
Karafka::Admin.read_partition_offsets(andAdmin::Topics#read_partition_offsets) exposing therd_kafka_ListOffsetsadmin API to query partition offsets by spec (:earliest,:latest,:max_timestamp, or a timestamp in ms) without a consumer group. Accepts an optionalisolation_level:keyword (passREAD_COMMITTEDfor the Last Stable Offset instead of the high-watermark, giving accurate lag on transactional topics). - [Feature] Add
Karafka::Connection::Client#read_partition_offsets(andConnection::Proxy#read_partition_offsets) exposing the batchedListOffsetsquery on a consumer's own connection, forwarding itsisolation.level. Note that:latestresolves to the high watermark regardless of isolation level, so it includes uncommitted messages on topics with in-flight transactions. - [Feature] Allow
Karafka::Admin(and subsystems likeAdmin::ConsumerGroups,Admin::Topics) to operate on an external client viaKarafka::Admin.new(external_client: client). Reuses the caller's client (no per-call bootstrap); its lifecycle stays with its owner. - [Feature] Add
Karafka::Admin::IsolationLevelsmodule withREAD_UNCOMMITTEDandREAD_COMMITTEDconstants wrapping the underlying rdkafka integer constants. - [Feature] Introduce standalone
Karafka::Declarativessubsystem (Declaratives::Topic,Declaratives::Repository,Declaratives::Builder) decoupled from routing. Topics can be declared viaKarafka::App.declaratives.draw; the existingrouting#config(...)DSL keeps working as a backwards-compatible bridge. - [Feature] Add
Processing::WorkersPoolwith dynamic thread pool scaling via#scale,nilsentinel-based worker exit for downscaling, andworker.scaling.up/worker.scaling.downinstrumentation events. - [Enhancement] Refresh watermark offsets and lags of long-paused partitions in
statistics.emitted(Pro). Opt-in viaconfig.internal.statistics.consumer_groups.lag_compensation.interval(ms, default0- disabled); partitions qualify after being paused for at leastlag_compensation.pause_age(ms, min5_000, default30_000). Refreshed values are kept on resume until live statistics catch up, then dropped in bulk on the next rebalance. - [Enhancement] Replace per-partition
query_watermark_offsetscalls with batchedlist_offsetsinAdmin::Topics#read_watermark_offsets,Admin::ConsumerGroups#seek, andPro::Iterator::TplBuilder#resolve_partitions_with_negative_offsets, cutting N sequential roundtrips to a small constant and avoiding a dedicated admin client in the iterator path (Pro). - [Enhancement] Add
stability_ttltoKubernetes::LivenessListenerandPro::Swarm::LivenessListenerto detect consumers frozen in a single non-"steady"librdkafkacgrp.join_state. On breach, reportsstability_ttl_exceeded: true(HTTP 500) / status code4; clears once the group returns to"steady". Requiresstatistics.interval.ms; defaults to twice the maxmax.poll.interval.msacross active subscription groups. - [Enhancement] Contain non-
StandardErrorerrors (ScriptError,SystemStackError, etc.) raised in the consumption flow through the normal retry/pause/DLQ flow instead of skipping the batch. Process-critical errors (SystemExit,SignalException,NoMemoryError) are recorded, keep the partition paused, and trigger a graceful shutdown via the auto-subscribedInstrumentation::CriticalErrorsListenerinstead of being retried or dispatched to the DLQ. Configurable viaconfig.internal.processing.critical_errors. - [Enhancement] Introduce polymorphic
Routing::Topic#groupandRouting::SubscriptionGroup#groupaccessors (#consumer_groupkept as a backwards-compatible alias), exposegroup_idinRouting::Topic#to_h, and emit parallelgroup/group_idkeys alongside the legacyconsumer_group/consumer_group_idkeys inrebalance.*,error.occurred, andstatistics.emittedpayloads. Prepares routing for KIP-932 share groups; legacy keys remain until Karafka 3.0. - [Enhancement] Add
Pro::Processing::ConsumerGroups::Filters::Actionsas the single source of truth for filter post-execution actions (Actions.skip/Actions.pause/Actions.seekvalue methods, theALLlist, and#skip?/#pause?/#seek?predicates mixed intoFilters::BaseandCoordinators::FiltersApplier). Returned values remain the same plain symbols, so existing filters keep working (Pro). - [Enhancement] Make the statistics decorator used by
Instrumentation::Callbacks::ConsumerGroups::Statisticsconfigurable viaconfig.internal.statistics.consumer_groups.decorator_classinstead of hardcodingKarafka::Core::Monitoring::StatisticsDecorator. - [Enhancement] Declare recurring tasks and scheduled messages internal topics via the standalone
Karafka::App.declaratives.drawDSL instead of the routingconfig(...)bridge; the resulting declarations are unchanged (Pro). - [Enhancement] CLI topic commands (
create,delete,reset,repartition,align,migrate,plan) now read fromKarafka::App.declaratives.topicsinstead of walking the routing tree, so topics declared viadeclaratives.draware managed without a routing entry. - [Enhancement] Add per-partition generation tracking to
AssignmentsTrackerto distinguish first-time assignments from reassignments. - [Enhancement] Make liveness listeners fiber-safe.
- [Enhancement] Bump swarm supervisor
SHUTDOWN_GRACE_PERIODfrom 1s to 15s to give forked nodes enough time to finish post-shutdown_timeoutcleanup before forceful termination. - [Enhancement] Move consumer-group-specific
Processingcomponents (Coordinator,CoordinatorsBuffer,Executor,ExecutorsBuffer,Partitioner,ExpansionsSelector,InlineInsights) and their Pro equivalents under theConsumerGroupsnamespace (internal). Related config defaults are updated; user-provided classes are unaffected. - [Enhancement] Move processing strategies (
Processing::Strategies::*andPro::Processing::Strategies::*) under theConsumerGroupsnamespace (internal), preparing for parallelShareGroups::Strategies(KIP-932). - [Enhancement] Move
Processing::StrategySelector(OSS and Pro) under theConsumerGroupsnamespace (internal); theconfig.processing.strategy_selectordefault is updated, user selectors unaffected. - [Enhancement] Move
Karafka::Connection::RebalanceManagertoConnection::ConsumerGroups::RebalanceManager(internal). - [Enhancement] Move the rebalance librdkafka callback to
Instrumentation::Callbacks::ConsumerGroups::Rebalance(internal); event names and payloads unchanged. - [Enhancement] Move
Instrumentation::Callbacks::ErrorandCallbacks::StatisticsunderCallbacks::ConsumerGroups(internal), completing the callbacks-layer namespacing; event names and payloads unchanged. - [Enhancement] Namespace consumer-group-specific processing job classes under
Processing::ConsumerGroups::Jobs(OSS) andPro::Processing::ConsumerGroups::Jobs(Pro); onlyJobs::Basestays generic. Internal move, no public API changes. - [Enhancement] Move
Processing::JobsBuilder(OSS and Pro) under theConsumerGroupsnamespace (internal). - [Enhancement] Nest consumer-group-specific processing config settings (
coordinator_class,errors_tracker_class,partitioner_class,strategy_selector,expansions_selector,executor_class,jobs_builder) underconfig.internal.processing.consumer_groups; shared settings stay atconfig.internal.processing. - [Enhancement] Move OSS consumer-group-specific routing features (
ActiveJob,DeadLetterQueue,Eofed,InlineInsights,ManualOffsetManagement) underRouting::Features::ConsumerGroups(internal); agnostic features stay put. - [Enhancement] Move Pro consumer-group-specific routing features under
Pro::Routing::Features::ConsumerGroups(internal); agnostic features (Expiring,Filtering,Pausing,Throttling) stay put. - [Change] Require
karafka-rdkafka>= 0.28.0, which exposesRdkafka::Consumer#list_offsetsand rebuilds#lagon top of it, so lag reads issue a single batched end-offsets query instead of one watermark roundtrip per partition. - [Change] Require
karafka-rdkafka>= 0.27.1for thepoll_batch/poll_batch_nbfix that discarded topic/partition/offset context frome.details, causingTopicNotFoundErrorcrashes onpartition_eof. - [Change] Remove the public
custom_kafkareader fromKarafka::Admin(internal collaboration detail, unused by any public API; custom kafka settings are provided at construction viaKarafka::Admin.new(kafka: ...)). - [Refactor] Remove the unused
@mutexfromPro::Connection::Manager(dead since #1851 replaced lock-based@changeseviction with key preloading; the lock-free threading model is now documented) (Pro). - [Maintenance] Split declarative topic configuration from routing in the integration suite: add a
draw_topicsspec helper wrappingKarafka::App.declaratives.draw, source spec topic creation from the declaratives repository, and migrate general integration specs to declare partitions/config viadraw_topics. - [Maintenance] Replace manual per-version
Warning[:performance]/Warning[:deprecated]spec setup with a dynamicWarning.categories-based approach that enables all non-experimental warning categories automatically. - [Maintenance] Use namespaced topic naming format in all integration specs for consistent traceability.
- [Maintenance] Add
bin/tests_topics_hashesscript for looking up spec files by their topic name hash prefix. - [Maintenance] Fix flaky
pro/admin/recovery/coordinator_for_spec.rbby warming up the__consumer_offsetstopic and retrying the firstRecovery.coordinator_forcall with exponential backoff onMetadataError. - [Fix] Compare recurring task schedule versions with
Gem::Versioninstead of as strings, so multi-segment upgrades like1.9.0→1.10.0are no longer misread as downgrades and rejected withIncompatibleScheduleError(Pro). - [Fix] Fix dynamic multiplexing
scale_delaybeing applied globally instead of per subscription-group family (Pro::Connection::Manager#stable?memoized the first family's value for all); it is now read per family on every check (Pro). - [Fix] Make
Routing::Topics#<<copy-on-write so a topic discovered at runtime by a pattern subscription can no longer be observed mid-append by a concurrent reader (e.g.Router#find_byfrom aPro::IteratororAdmincall on another thread). - [Fix] Bound
Instrumentation::AssignmentsTracker's@generationsmap (GENERATIONS_TOPICS_LIMIT, LRU eviction) so it no longer grows for the whole process lifetime under regex pattern subscriptions; static topologies are unaffected. - [Fix] Derive the filtering pause timeout only from filters that actually want to pause, so a coexisting
:seekfilter reporting a0timeout no longer collapses a:pauseto0and busy-spins (Pro). - [Fix] Clamp scheduled message CreateTime to the wall clock in the loaded heuristic, so a single future-dated message can no longer be taken as proof of catch-up and cause double dispatch of not-yet-loaded cancellations (Pro).
- [Fix] Reset
Pro::Iterator#eachEOF/stop tracking in anensure, so breaking out of the yielded block no longer leavesdone?immediately true and silently drops a fresh backlog on reuse (Pro). - [Fix] Fix the
parallel_segmentsCLI commands (distribute,collapse,reset) silently skipping groups when more than one was requested via--groups(the matched group was deleted from the array being iterated); all requested groups are now processed (Pro). - [Fix] Evict a partition's samples from
Pro::Instrumentation::PerformanceTrackeron revoke and scope samples by subscription group id, fixing unbounded growth and cross-group interference. Breaking (internal API):processing_time_p95now takes the subscription group id first (processing_time_p95(group_id, topic, partition)) (Pro). - [Fix] Fall back to the current offset metadata (instead of raising
KeyError) in Virtual PartitionsVirtualOffsetManager#markableunder the:exactstrategy when the lowest-offset virtual-partition group is left unmarked (Pro). - [Fix] Leave tombstone records (key with a
nilpayload) untouched on produce and consume instead of crashing incipher.encrypt/decrypt, so they remain valid tombstones for log compaction (Pro). - [Fix] Recompute the
Pro::Processing::JobsQueue#clearasync-locking fast-path flag from the remaining groups' locks instead of forcing it off globally, so another subscription group's activelock_asynclocks are no longer ignored (Pro). - [Fix] Reset the per-partition retry attempt counter on revocation, so a message reclaimed after a rebalance is no longer treated as having exhausted its retries and dispatched to the DLQ early.
- [Fix] Reset ActiveJob
CurrentAttributesin anensure, so a failed job's attributes no longer leak into the next job on the same worker. - [Fix] Return
falsefrom#mark_as_consumed,#mark_as_consumed!, and#commit_offsets!when the operation fails because the partition was lost (previously could returntrue). - [Fix] Reset
seek_offsetonly after a#seeksucceeds, so a raising seek (e.g. an unresolvable time-based offset) no longer pauses without seeking back and skips the rest of the batch. - [Fix] Skip DLQ dispatch when the partition was revoked mid-job in the ActiveJob + DLQ + long-running job strategies (matching the non-AJ LRJ strategies), so the new owner handles it instead of producing a duplicate (Pro).
- [Fix] Advance the in-memory
seek_offsetonly after a transactional DLQ dispatch succeeds, so an aborted dispatch transaction withmark_after_dispatch: falseno longer skips the broken message (Pro). - [Fix] Report ownership truthfully from Virtual Partitions
#mark_as_consumed/#mark_as_consumed!when there is no real offset to materialize yet (previously inverted) (Pro). - [Fix] Stop reverting recurring task commands consumed during the boot replay phase, which previously persisted the reverted state and lost the command permanently (Pro).
- [Fix] Always precede Virtual Partitions DLQ
:dispatch/:skipdecisions with a collapsed retry, so they run on the linear deterministic flow instead of an arbitrary virtual-partition subset that could lose messages or dispatch the wrong one (Pro). - [Fix] Compare scheduled messages schema versions as
Gem::Versioninstead of strings, fixing mis-evaluation once a version segment reaches two digits (Pro). - [Fix] Fix
Karafka::Admin.read_topicwith aTimestart offset beyond the last message returning the newest messages instead of none. - [Fix] Prevent silent worker thread death draining the workers pool: worker continuation is now an explicit framework decision (only a closed queue or downscale sentinel stops a worker), so a user
Consumer#wrapreturning a falsy value no longer kills the thread. - [Fix] Track
Pro::IteratorEOF and explicit stops per topic-partition instead of globally, so a partition receiving new data mid-iteration no longer exhausts the EOF budget and terminates#eachwhile others still have backlog;#eachalso resets#stopon finish so the iterator can be reused (Pro). - [Fix] Include orphaned node detection in the Pro swarm liveness listener.
- [Fix] Report liveness on
connection.listener.before_fetch_loopso nodes send an initial healthy report before the first consumption. - [Fix] Fire liveness events during
wait_pingingso nodes keep reporting health during shutdown with active LRJ jobs. - [Fix] Fix
DataCollector::SPEC_HASHproducing non-deterministic hashes for pristine and poro specs by passing the original spec path via theKARAFKA_SPEC_PATHenv var. - [Fix] Fix the swarm supervisor leaking reader pipe file descriptors on node restarts by closing the old reader before creating a new pipe in
Node#start. - [Fix] Raise
InvalidLicenseTokenErrorwhen a manually-definedKarafka::Licensemodule is missing#tokenor#versioninstead of silently skipping Pro loading and raising a confusingNameErrorlater in boot.