
Kafka Support, Consulting and 24/7 Performance Engineering
MinervaDB operates, tunes and rescues Apache Kafka event-streaming platforms for teams that cannot tolerate a stalled pipeline. This page is deliberately technical. It explains how the distributed commit log behaves under load, which configuration knobs actually move latency and throughput, how to size hardware, and how our engineers diagnose Kafka failures in production.
If you are comparing Apache Kafka support vendors, treat the sections below as a checklist of what a competent partner should already know before touching your cluster. Everything here comes from incident work rather than marketing copy: broker saturation at 03:00, consumer groups trapped in a rebalance loop, silent data loss after an unclean leader election, and cost blowouts caused by nothing more exotic than a badly chosen partition count.
Contents
- Reference architecture of a production Kafka platform
- The Kafka distributed log: partitions, segments and offsets
- Kafka replication, in-sync replicas and durability
- The Kafka producer path and write-side tuning
- Kafka consumer groups, rebalancing and lag
- Kafka KRaft metadata quorum versus ZooKeeper
- Kafka transactions and exactly-once semantics
- Kafka retention, compaction and tiered storage
- Kafka capacity planning arithmetic
- Kafka broker, JVM and operating-system tuning reference
- Kafka observability: the metrics that actually matter
- Kafka multi-region topologies and disaster recovery
- Kafka security hardening: mTLS, SASL and ACLs
- Kafka failure modes and how we diagnose them
- MinervaDB Kafka support catalogue and SLAs
- Frequently asked questions
Reference Architecture of a Production Kafka Platform
A healthy Kafka deployment is layered. Publishers never write to storage directly, subscribers never depend on a single node, and cluster metadata lives in its own replicated quorum. The Kafka topology below is the shape we deploy, review and support most often.
PUBLISHERS KAFKA BROKER TIER (N nodes) SUBSCRIBERS
+----------------+ +----------------------------+ +-----------------+
| App services | | broker-1 broker-2 | | Stream jobs |
| CDC / Debezium | ---> | [P0 L][P1 F] [P0 F][P1 L] ---> | Flink, Streams |
| Edge + mobile | mTLS | [P2 F][P3 L] [P2 L][P3 F] | Sink connectors |
| Log shippers | | broker-3 | | OLAP + search |
+----------------+ | [P0 F][P1 F][P2 F][P3 F] | +-----------------+
| +-------------+--------------+ |
| | metadata RPC |
| +------------v-------------+ |
| | KRaft controller quorum | |
| | 3 or 5 voters, Raft log | |
| +--------------------------+ |
| |
+----------------- schema registry + governance ------------------+
L = partition leader F = in-sync follower P0..P3 = partitions
Three design rules govern every Kafka cluster we build. First, the metadata quorum is sized for an odd number of voters so a majority always exists; three voters tolerate one failure, five tolerate two. Second, replicas of the same partition are spread across fault domains using broker.rack, so a rack, availability zone or hypervisor loss never removes a majority of a partition’s replicas. Third, the client tier is isolated from storage decisions by a schema contract, which lets us evolve payloads without redeploying every consumer.
We also insist on separating workload classes onto different listeners and, where volume justifies it, different broker pools. Mixing a bursty clickstream with a low-latency payments topic on the same disks is the fastest route to unpredictable tail latency.
The Kafka Distributed Log: Partitions, Segments and Offsets
A Kafka topic is not a queue. It is a partitioned, append-only log, and each partition is an ordered, immutable sequence of records addressed by a monotonically increasing offset. Ordering is guaranteed inside a partition and nowhere else. That single property is the most frequently misunderstood aspect of the platform and the root cause of most “events arrived out of order” tickets we are asked to investigate.
topic "payments", 3 partitions, append-only, offsets never reused
partition-0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | <-- append at log end
partition-1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
partition-2 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
^
consumer group commits
offset 5 for partition-2
on-disk layout of partition-0
/var/lib/data/payments-0/
00000000000000000000.log records, closed segment
00000000000000000000.index offset -> byte position
00000000000000000000.timeindex timestamp -> offset
00000000000000368421.log ACTIVE segment (never deleted)
leader-epoch-checkpoint fencing data for truncation
partition.metadata
Segments roll when they exceed segment.bytes or segment.ms, and only closed segments are eligible for deletion or compaction. This is why a topic with a seven-day retention window and a one-gigabyte segment size can still hold data that is far older than seven days: the active segment has not rolled yet. We tune segment size against retention granularity rather than leaving both at defaults.
Keying, partition assignment and hot partitions
The default Kafka partitioner hashes the record key with murmur2 and takes the modulus of the partition count. Two operational consequences follow. Records sharing a key always land on the same partition and therefore preserve relative order, and increasing the partition count permanently breaks that mapping for existing keys. Partition counts are a one-way door, so we plan them during design review instead of discovering the problem during a migration.
| Symptom | Likely cause | Remedy we apply |
| One partition 20x the size of its peers | Low-cardinality or skewed key, for example tenant_id where one tenant dominates | Composite key, salted key, or custom partitioner with explicit routing |
| Lag concentrated on a single consumer | Hot partition pinned to one group member | Re-key the topic, split the tenant into a dedicated topic |
| Throughput plateau despite adding consumers | Consumers exceed partition count, so extras idle | Raise partitions with a planned re-key, or fan out downstream |
| Ordering violations after a scale-up | Partition count changed, hash modulus moved | Dual-write migration to a new topic with the final partition count |
As a planning heuristic we keep partitions per Kafka broker in the low thousands, allow at least one partition per unit of intended consumer parallelism, and leave 30–40 percent headroom for future growth. Every partition costs an open file handle set, a replication fetch slot and a slice of controller metadata, so more is not free.
Kafka Replication, In-Sync Replicas and Durability Guarantees
Kafka durability is decided by the interaction of three settings: the replication factor, min.insync.replicas, and the producer acknowledgement mode. Getting any one of them wrong silently converts a “no data loss” design into a best-effort one.
partition P0 replication.factor = 3 min.insync.replicas = 2
leader broker-1 | 0 1 2 3 4 5 6 7 8 | LEO = 9 HW = 7
follower broker-2 | 0 1 2 3 4 5 6 7 | LEO = 8 in ISR
follower broker-3 | 0 1 2 3 4 5 6 7 | LEO = 8 in ISR
follower broker-4 | 0 1 2 3 | LEO = 4 OUT of ISR (lagging)
^
High Watermark (HW): highest offset replicated to every
ISR member. Consumers can only read up to the HW, so a
record is never visible before it is durably replicated.
LEO = Log End Offset (next offset to be written)
replica falls out of ISR when it has not fetched within
replica.lag.time.max.ms (default 30s)
| acks | Write is acknowledged when | Loss window | Typical fit |
| 0 | The client hands bytes to the socket | Everything in flight | Disposable telemetry only |
| 1 | The leader writes to its own page cache | Leader crash before replication | Metrics, logs, low-value events |
| all | Every ISR member has the record | Only a simultaneous loss of all ISR members | Payments, ledgers, CDC, audit |
With acks=all and min.insync.replicas=2 on a three-replica partition, the cluster tolerates one broker failure with no loss and no availability impact, and it deliberately rejects writes with NOT_ENOUGH_REPLICAS if a second replica also fails. That rejection is a feature: it trades availability for correctness at the exact moment the guarantee would otherwise be violated.
We keep unclean.leader.election.enable=false on every business-critical Kafka topic. Enabling it allows an out-of-sync replica to become leader, which truncates committed records and produces the hardest class of data-loss incident to explain after the fact. Leader epochs and the leader-epoch-checkpoint file exist precisely to make truncation deterministic, and they only work if unclean elections stay disabled.
The Kafka Producer Path and Write-Side Tuning
Most throughput complaints we receive are not Kafka broker problems at all. They are client problems: unbatched sends, a single producer instance shared by hundreds of threads, or a compression codec chosen without measuring CPU cost. Understanding the write path makes the fix obvious.
send(record)
|
v
serializer (Avro / Protobuf / JSON + schema id)
|
v
partitioner (murmur2(key) % partitions, or sticky when key is null)
|
v
RecordAccumulator per-partition batch buffers
+-----------------------------------------------+
| P0: [ rec rec rec ] 16 KB batch.size |
| P1: [ rec rec ] |
| P2: [ rec ] |
+-----------------------------------------------+
| flush trigger: batch full OR linger.ms elapsed
v
Sender thread (one per client instance)
| max.in.flight.requests.per.connection = 5
| enable.idempotence = true -> sequence numbers per partition
v
broker: validate -> append to page cache -> (fsync by OS)
|
| acks=all: wait until min.insync.replicas have fetched
v
ack (or retriable error -> retry with same sequence number)
| Setting | Default | What we usually set | Why |
batch.size |
16 KB | 64–256 KB | Fewer, larger requests cut per-request overhead dramatically |
linger.ms |
0 | 5–50 ms | Buys batching at a bounded, predictable latency cost |
compression.type |
none | zstd or lz4 | zstd for storage and network savings, lz4 when CPU is the constraint |
enable.idempotence |
true | true | Removes duplicates caused by retries without a transaction |
max.in.flight.requests.per.connection |
5 | 5 with idempotence | Ordering is still preserved because sequences are checked |
buffer.memory |
32 MB | 128–512 MB | Absorbs bursts instead of blocking the calling thread |
delivery.timeout.ms |
120 s | Aligned to business SLA | Caps total time a record can sit in retry limbo |
Kafka compression is applied per batch, not per record, which is why linger.ms=0 and compression together often deliver worse ratios than no compression at all. We also standardise on Kafka broker-side compression.type=producer so the cluster never spends CPU recompressing what the client already compressed.
Kafka Consumer Groups, Rebalancing and Lag
A Kafka consumer group is a coordination protocol, not just a label. The group coordinator assigns partitions, tracks liveness through heartbeats, and stores committed offsets in the internal __consumer_offsets topic. Rebalances are where availability is usually lost.
group "fraud-scoring" topic "payments" (6 partitions)
BEFORE scale-out AFTER adding member C3
C1 -> P0 P1 P2 C1 -> P0 P1
C2 -> P3 P4 P5 C2 -> P2 P3
C3 -> P4 P5
EAGER protocol (legacy)
join -> REVOKE ALL -> compute -> assign -> resume
|______ stop-the-world pause for the whole group ______|
COOPERATIVE-STICKY protocol (what we deploy)
join -> compute -> revoke ONLY the partitions that move
-> second rebalance assigns them -> others never stop
liveness: session.timeout.ms (heartbeat thread)
progress: max.poll.interval.ms (application processing time)
Two Kafka client timeouts are routinely confused. session.timeout.ms governs the background heartbeat and detects a dead process. max.poll.interval.ms governs how long the application may spend processing a batch before the coordinator assumes it is stuck. A slow database write inside the poll loop triggers the second, not the first, and the resulting eviction looks like a network problem to the untrained eye. The fix is usually to lower max.poll.records and move blocking work off the poll thread.
Kafka consumer lag is the arithmetic difference between the partition log end offset and the group’s committed offset. We alert on the derivative rather than the absolute value, because a batch job legitimately sits at high lag while a steadily climbing lag on a real-time topic is an emergency.
lag(partition) = log_end_offset - committed_offset time_to_drain = lag / (consume_rate - produce_rate) when consume > produce healthy lag ~~~~~~~~~~~~~~~~ flat, small, sawtooth falling behind lag ///////// monotonic climb -> page someone stalled lag --------- flat but large -> stuck consumer rebalance storm lag //// repeated spikes -> timeout tuning
Kafka KRaft Metadata Quorum Versus ZooKeeper
Modern Kafka clusters replace the external coordination service with a built-in Raft quorum that stores metadata in a dedicated internal log. For teams still running the older architecture, migration is one of the most common engagements we are asked to plan and execute.
LEGACY (ZooKeeper) KRaft
+-------------------+ +---------------------------+
| ZK 1 ZK 2 ZK 3 | | controller-1 (Raft leader)|
+---------+---------+ | controller-2 (voter) |
^ znodes: topics, | controller-3 (voter) |
| ISR, configs, ACLs +-------------+-------------+
| | __cluster_metadata
+---------+---------+ +-------------v-------------+
| brokers + one | | brokers replay the |
| active controller | | metadata log locally and |
+-------------------+ | cache it in memory |
+---------------------------+
failover: seconds to minutes | failover: sub-second
practical partition ceiling: | practical ceiling an order of
tens of thousands | magnitude higher
two security models to manage | one security model
The operational win for Kafka operations is not merely fewer moving parts. Because every broker holds an up-to-date replica of the metadata log, controller failover no longer requires reloading state from an external store, so recovery time becomes largely independent of cluster size. Our Kafka migration runbook covers voter sizing, dual-write bridge mode, rollback checkpoints, and validation of every ACL and dynamic config before the old coordination layer is decommissioned.
Kafka Transactions and Exactly-Once Semantics
Exactly-once is achievable, but only for the read-process-write pattern inside Kafka, and only when producers, consumers and the state store all participate. We spend a lot of time correcting the belief that setting one flag delivers it end to end.
consume -> transform -> produce, atomically
1. initTransactions() producer.id + epoch fenced by coordinator
2. beginTransaction()
3. send(outputTopic, ...) markers written to partitions
4. sendOffsetsToTransaction(consumedOffsets, groupId)
5. commitTransaction()
|
v
transaction coordinator writes COMMIT marker to __transaction_state
and control records to every touched partition
reader side: isolation.level = read_committed
|A A A|C| -> visible (C = commit marker)
|B B B|X| -> filtered out (X = abort marker)
Last Stable Offset (LSO) <= High Watermark: read_committed
consumers stop at the LSO, so one long transaction blocks
visibility for every later record in that partition.
The practical cost of Kafka transactions is throughput and latency: commit markers add round trips, and a hung transaction pins the last stable offset, which stalls all read_committed readers on that partition until transaction.timeout.ms expires. We therefore keep transaction scope small, measure the overhead against the alternative of idempotent writes with downstream deduplication, and only recommend full transactional pipelines where the business genuinely cannot tolerate duplicates.
Kafka Retention, Compaction and Tiered Storage
Kafka storage policy is where cost control lives. Two cleanup policies exist and they solve different problems: time or size based deletion for event streams, and key-based compaction for changelog or state topics.
cleanup.policy = delete cleanup.policy = compact
drop whole segments once retain the latest value per key
retention.ms / retention.bytes
is exceeded
BEFORE compaction
| k1=v1 | k2=v1 | k1=v2 | k3=v1 | k2=v2 | k1=v3 | k4=null |
^ superseded ^ superseded
AFTER compaction (tail rewritten, offsets preserved, gaps allowed)
| k3=v1 | k2=v2 | k1=v3 | (k4=null tombstone removed
after delete.retention.ms)
Kafka log compaction never touches the active segment, runs on the cleaner threads governed by log.cleaner.threads and min.cleanable.dirty.ratio, and preserves original offsets, which is why a compacted topic legitimately shows offset gaps. A cleaner that cannot keep up is a common hidden cause of disks filling on a topic that “should” be bounded.
Tiered storage
BROKER LOCAL DISK (hot) OBJECT STORE (warm/cold)
+--------------------------+ +---------------------------+
| active + recent segments | ---> | offloaded closed segments |
| NVMe, low latency reads | copy | S3 / GCS / Azure Blob |
| local.retention.ms | | retention.ms (long tail) |
+-----------+--------------+ +-------------+-------------+
| |
| consumer reads recent data |
+------------------> broker <---------+
remote fetch for historical replay
effect: local disk sized for the working set, not for retention;
cluster rebalance and broker replacement become far faster because
there is much less local data to move.
Kafka tiered storage changes capacity planning fundamentally. Local disk is sized for the hot working set while long retention moves to object storage at a fraction of the cost, and broker replacement stops being a multi-hour data-shuffling exercise. The trade-off is higher and less predictable latency for historical reads, so we validate replay performance against real backfill jobs before recommending it.
Kafka Capacity Planning Arithmetic
We refuse to size Kafka clusters by intuition. The model below is deliberately simple and has survived contact with production many times.
ingress_raw = events_per_sec * avg_event_bytes
ingress_on_wire = ingress_raw / compression_ratio
replication_load = ingress_on_wire * (replication_factor - 1)
broker_egress = ingress_on_wire * consumer_group_count
+ replication_load
daily_storage = ingress_on_wire * 86400 * replication_factor
retained_storage = daily_storage * retention_days * (1 + headroom)
partitions_min = max( target_throughput / per_partition_throughput ,
required_consumer_parallelism )
WORKED EXAMPLE
200,000 events/sec, 1.2 KB average, zstd ratio 4:1, RF=3,
3 consumer groups, 7 day retention, 40% headroom
ingress_raw = 240 MB/s
ingress_on_wire = 60 MB/s
replication_load = 120 MB/s
broker_egress = 300 MB/s (fleet aggregate)
daily_storage = 60 MB/s * 86400 * 3 = 15.5 TB/day
retained_storage = 15.5 * 7 * 1.4 = 152 TB
-> 9 brokers with 20 TB usable NVMe each, 25 GbE, or the same
ingest with ~2 days local retention plus tiered storage.
Notice that Kafka replication and fan-out, not raw ingest, dominate network sizing. A cluster that comfortably accepts 60 MB/s of writes can still saturate its network interfaces once three replicas and three consumer groups are accounted for. This is the calculation most often skipped in self-designed deployments.
Kafka Broker, JVM and Operating-System Tuning Reference
| Layer | Parameter | Guidance |
| Broker | num.network.threads / num.io.threads |
Network threads near core count; I/O threads at roughly two times the number of data directories |
| Broker | num.replica.fetchers |
Raise to 4–8 on high-partition clusters so followers keep pace and the ISR stays stable |
| Broker | socket.send.buffer.bytes |
1 MB or more on high bandwidth-delay-product links, especially cross-region replication |
| Broker | log.flush.interval.messages |
Leave unset; rely on replication for durability rather than synchronous flush |
| JVM | Heap size | 6–12 GB is almost always correct; the page cache, not the heap, serves reads |
| JVM | Collector | G1 with a 20 ms pause target, or ZGC on very large heaps; alert on pauses above 100 ms |
| OS | vm.swappiness |
1, so the page cache is never swapped out under memory pressure |
| OS | vm.dirty_ratio / dirty_background_ratio |
Lower the background ratio to smooth writeback spikes and avoid latency cliffs |
| OS | File descriptors | At least 100,000; every segment and connection consumes handles |
| Storage | Filesystem | XFS with noatime; separate data directories per physical device, never RAID 5 |
| Network | MTU and offload | Consistent MTU end to end; verify that segmentation offload is enabled on all hosts |
The single most valuable Kafka tuning rule on this list is heap sizing. Zero-copy transfer from the page cache is what makes the log fast, so memory handed to the JVM is memory taken away from the mechanism that actually serves your consumers.
Kafka Observability: The Metrics That Actually Matter
Dashboards with two hundred panels are not observability. These are the Kafka signals we wire up first on every engagement, because each one maps directly to a decision.
| Signal | Source | Why it matters | Action threshold |
UnderReplicatedPartitions |
Broker JMX | Replicas are behind, so durability is degraded right now | Any non-zero value sustained beyond a minute |
OfflinePartitionsCount |
Controller JMX | Partitions have no leader and are unavailable | Page immediately on any non-zero value |
ActiveControllerCount |
Controller JMX | Must sum to exactly one across the cluster | Zero or greater than one is a split-brain risk |
IsrShrinksPerSec |
Broker JMX | Flapping replicas usually mean disk or network saturation | Repeated shrink and expand cycles |
RequestQueueTimeMs p99 |
Broker JMX | Distinguishes queueing delay from real work | Rising queue time with flat local time means thread starvation |
RequestHandlerAvgIdlePercent |
Broker JMX | Direct measure of I/O thread saturation | Below 30 percent means add threads or brokers |
| Consumer group lag | Admin API | The only true measure of business freshness | Alert on sustained positive slope, not absolute value |
| Log flush latency p99 | Broker JMX | Detects a failing or throttled disk before it takes a broker down | Deviation from the fleet baseline |
| GC pause duration | JVM | Long pauses cause spurious ISR shrinks and session timeouts | Any pause beyond 100 ms |
| Produce error rate by type | Client metrics | NOT_ENOUGH_REPLICAS and timeouts have completely different fixes |
Any sustained non-zero rate |
We instrument Kafka clients as aggressively as brokers. Server-side dashboards that look perfect while a producer quietly buffers and drops records are one of the most dangerous blind spots in streaming operations, and client metrics are the only place that failure is visible.
Kafka Multi-Region Topologies and Disaster Recovery
There is no single correct cross-region Kafka design, only trade-offs between recovery point objective, recovery time objective, write latency and cost. We choose between three patterns.
(1) ACTIVE / PASSIVE with asynchronous replication REGION A (write) REGION B (standby) [cluster] --- MirrorMaker 2 ---> [cluster] RPO: seconds to minutes RTO: minutes (offset translation needed) cheapest, simplest, small but real data-loss window (2) ACTIVE / ACTIVE with prefixed remote topics REGION A <===== bidirectional MM2 =====> REGION B orders a.orders / b.orders orders RPO: seconds RTO: near zero for reads requires consumers that understand remote topic naming and application-level conflict handling (3) STRETCH CLUSTER across three low-latency zones ZONE 1 ZONE 2 ZONE 3 [brokers] === [brokers] === [brokers] one logical cluster rack-aware replica placement, min.insync.replicas = 2 RPO: zero RTO: automatic failover requires sub-10 ms inter-zone latency; not viable across continents
Whichever Kafka pattern is chosen, the recovery plan is only real if it is exercised. Our Kafka disaster-recovery engagements include scripted failover drills, consumer offset translation verification, and a documented decision tree for the human on call. We also verify that schema registry state, connector configurations and ACLs are replicated, because a cluster that comes up without them is not actually a recovered service.
Kafka Security Hardening: mTLS, SASL and ACLs
CLIENT BROKER
| 1. TLS handshake, both sides present certificates
|----------------------------------------------->|
| 2. SASL authentication (SCRAM-SHA-512, GSSAPI,
| or OAUTHBEARER against your identity provider)
|----------------------------------------------->|
| 3. Principal extracted -> mapped via
| ssl.principal.mapping.rules
| 4. Authorizer checks ACLs
| (principal, operation, resource, host)
|<-----------------------------------------------|
| 5. Allowed operations only; quotas applied per principal
listeners:
INTERNAL :9092 broker-to-broker, mTLS
EXTERNAL :9093 clients, TLS + SASL
CONTROLLER:9094 metadata quorum only, never client reachable
at rest: full-disk or volume encryption, plus payload-level
encryption for regulated fields the platform must not read.
Least privilege in Kafka is enforced with explicit allow rules per principal and resource, wildcard grants are removed, and quotas cap the damage any single misbehaving client can do. We treat the controller listener as strictly internal, run regular ACL drift audits, and keep credential rotation scripted so it is a routine change rather than a project.
Kafka Failure Modes and How We Diagnose Them
| What you observe | Underlying cause we usually find | Resolution |
| Producer timeouts under normal load | Request queue saturation, or a leader on a broker with a degraded disk | Add I/O threads, move leadership, replace the device |
| Endless rebalance loop | max.poll.interval.ms exceeded by slow downstream calls |
Reduce max.poll.records, make processing asynchronous, adopt cooperative-sticky assignment |
| Lag grows only on some partitions | Key skew creating a hot partition | Re-key, salt the key, or isolate the noisy tenant |
| Disk fills despite short retention | Log cleaner starved, or a huge active segment that never rolled | Add cleaner threads, tune segment size and dirty ratio |
| Records disappear after a node restart | Unclean leader election combined with acks=1 |
Disable unclean election, move to acks=all with min.insync.replicas=2 |
| Consumers stall at a fixed offset | A hung transaction pinning the last stable offset | Lower transaction.timeout.ms, fence the zombie producer, shrink transaction scope |
| Cross-region replication falls behind | Undersized socket buffers on a high-latency link | Enlarge send and receive buffers, increase fetcher parallelism |
| Periodic latency spikes every few minutes | Garbage collection pauses or page-cache writeback storms | Right-size the heap, tune dirty ratios, tune the collector |
| Schema evolution breaks a downstream job | No compatibility policy enforced in the registry | Enforce backward compatibility in CI and gate deployments on it |
Our Kafka diagnostic method is consistent: establish whether the constraint is client-side, network, storage or coordination before changing anything. Configuration changes made without that classification are how a one-hour incident becomes a three-day one.
MinervaDB Kafka Support Catalogue and Service Levels

1. Architecture design and design review
We design Kafka topic taxonomies, partition and key strategies, replica placement across fault domains, retention and compaction policy, and the metadata quorum layout. Existing deployments get a written review with prioritised, quantified findings rather than a generic best-practice list.
2. Performance engineering
Throughput and tail-latency work across the whole Kafka path: producer batching and compression, broker thread pools and file systems, replication fetcher parallelism, consumer poll-loop design, and stream-processing state stores. We benchmark before and after so the improvement is a number, not an opinion.
3. 24/7 consultative support and incident response
Follow-the-sun Kafka coverage from engineers who operate distributed logs for a living. We join your incident channel, drive root-cause analysis, and deliver a written post-incident report with concrete preventive changes.
4. Migrations and upgrades
Kafka version upgrades, coordination-layer migration to the Raft-based metadata quorum, self-managed to cloud moves, cloud to self-managed repatriation for cost reasons, and cross-cloud replication cutovers. Every plan includes rollback checkpoints and validation gates.
5. Pipeline and integration engineering
Change-data-capture ingestion into Kafka, connector development and hardening, stream processing with Flink or the Streams library, and delivery into analytical stores. See our related work on data strategy and analytics and vector data engineering for how streaming fits a wider platform.
6. Cost optimisation
Right-sizing Kafka brokers, tiered storage adoption, compression and retention policy tuning, partition rationalisation, and elimination of redundant replication traffic. Reducing infrastructure spend by a third without touching durability guarantees is a common outcome.
7. Security, compliance and governance
Kafka authentication and authorisation design, ACL rationalisation, encryption in transit and at rest, quota policy, audit logging, and evidence packages for regulated environments.
| Tier | Coverage | First response | Best for |
| Advisory | Business hours, scheduled review sessions | 1 business day | Teams building their first streaming platform |
| Production | 24 x 7 for severity 1 and 2 | 30 minutes for severity 1 | Revenue-bearing real-time pipelines |
| Mission critical | 24 x 7 x 365, named engineers, quarterly game days | 15 minutes for severity 1 | Payments, trading, fraud detection, telemetry at scale |
| Project | Fixed-scope engagement | By agreement | Migrations, upgrades, audits, capacity studies |
How an engagement starts
WEEK 0 discovery: Kafka topology, versions, topics, clients, SLOs
|
WEEK 1 instrumented baseline: throughput, p99 latency, lag,
| ISR stability, storage growth, cost per event
|
WEEK 2 findings report: ranked issues, effort vs impact,
| quantified risk for each durability gap
|
WEEK 3-4 remediation in staging, then controlled production
| rollout with rollback checkpoints at every step
|
ONGOING 24/7 coverage, monthly performance review,
capacity forecast, quarterly failover drill
Frequently Asked Questions
How many partitions should a Kafka topic have?
Enough to meet your throughput target and to allow the consumer parallelism you need, plus roughly 30 to 40 percent headroom. Because increasing the count reshuffles key-to-partition mapping, we size it at design time using the arithmetic in the capacity section rather than adjusting it later.
Do we still need ZooKeeper with Kafka?
New Kafka clusters should be built on the Raft-based metadata quorum, and existing ZooKeeper-backed clusters should have a dated migration plan. The benefits are faster controller failover, a much higher practical partition ceiling and one security model instead of two.
Can we get exactly-once delivery end to end?
Atomic read-process-write is achievable within Kafka using transactions and read_committed isolation. Once data leaves for an external system, you need either an idempotent sink or a transactional sink; otherwise the correct design is at-least-once delivery with downstream deduplication.
What causes most Kafka production incidents?
In our experience, client misconfiguration and partition skew cause more outages than Kafka broker failures. Defaults that are safe for a laptop are frequently wrong for a cluster handling hundreds of thousands of events per second.
Should we self-manage Kafka or use a managed service?
It depends on data-gravity, latency requirements, compliance constraints and the true total cost at your volume. We model both options with your real numbers, and we support either choice; our value is engineering judgement, not a licence resale margin.
Do you work alongside our existing Kafka team?
Yes. Most engagements are collaborative: we embed with your engineers, transfer knowledge deliberately, and leave behind runbooks, dashboards and tuned configurations that your team owns.
Talk to MinervaDB About Your Kafka Platform
Whether you need a second opinion on a Kafka architecture, an urgent hand on a live incident, or continuous 24/7 coverage for a revenue-critical pipeline, our Kafka engineers are available now. Bring us your topology, your metrics and your worst-performing topic, and we will tell you exactly what we would change and why.
Please contact us to schedule a technical consultation.

Further Reading
- Data Engineering and Analytics in Digital Payment Solutions
- Data Engineering and Analytics in Banking and FinTech
- Data Architecture, Engineering, and Operations for Digital Advertising Networks
- Data Strategy and Analytics
- Vector Data Engineering
- Upstream design documentation for the distributed commit log
MinervaDB Inc. — your trusted partner in real-time data streaming, performance engineering and mission-critical data infrastructure.