Amazon MSK: Managed Kafka Streaming — Production Patterns That Don't Fail at 3 AM
Amazon MSK deep dive: avoid common pitfalls, tune for throughput, and handle failures in production Kafka clusters on AWS..
20+ years shipping production infrastructure and CI/CD at scale. Everything here is grounded in real deployments.
- ✓Apache Kafka fundamentals (topics, partitions, consumer groups)
- ✓AWS networking basics (VPC, subnets, security groups)
- ✓Experience with distributed systems and at-least-once semantics
Amazon MSK is AWS's managed Kafka service. You create a cluster, configure topics, and connect producers/consumers — AWS handles broker health and ZooKeeper. But you must still tune for throughput, handle rebalances, and monitor lag yourself.
Think of Amazon MSK as a valet parking service for your Kafka cluster. You hand over the keys (your data streams), and they park the car (manage brokers and ZooKeeper). But you still decide how fast to drive (producer/consumer config), which route to take (topic partitioning), and what to do if the car breaks down (failure handling).
You've seen it. A Kafka cluster that was humming along at 10k messages/sec suddenly starts throwing connection timeouts at 2 AM. The pager goes off. You SSH in, see broker logs full of 'Not enough replicas', and realize your MSK cluster just silently dropped a broker. The managed part doesn't mean bulletproof. Amazon MSK handles the infrastructure — but your application code and topic design are still on you. This article walks through the production patterns that keep your Kafka pipeline alive when everything else is on fire. By the end, you'll know how to configure MSK for high throughput, handle rebalances without data loss, and debug the failure modes that actually happen.
Why MSK Isn't Magic — The Shared Responsibility Model
Amazon MSK manages the ZooKeeper ensemble and broker lifecycle. But you own the Kafka configuration, topic design, client tuning, and monitoring. The classic mistake is treating MSK like a fully managed black box. It's not. When a broker fails, MSK replaces it — but the new broker has no data. It must replicate from the remaining brokers. During that window, your min.insync.replicas setting can block producers. I've seen a payments pipeline stall for 20 minutes because someone set min.insync.replicas=3 on a 3-broker cluster. One broker went down, and no producer could write. The fix: always set min.insync.replicas to 2 on a 3-broker cluster, or use acks=1 for latency-sensitive workloads.
min.insync.replicas equal to replication.factor, a single broker failure will block all writes. Always leave at least one broker of slack.Tuning Producers for Throughput Without Losing Data
The default producer config is safe but slow. For high-throughput pipelines, you need to tune batch.size, linger.ms, and compression.type. The goal is to batch more messages per request without increasing latency beyond your SLA. Start with batch.size=65536 (64 KB) and linger.ms=10. Use snappy compression — it's fast and reduces network I/O. But here's the gotcha: if your producer is sending messages to many partitions, batching becomes less effective because each partition gets its own batch. The fix: ensure your partition count is reasonable (e.g., 6-12 per broker) and use a sticky partitioner to batch more messages to the same partition.
enable.idempotence=true and acks=all for critical data. The performance cost is negligible with batching.Consumer Design: Avoiding the Rebalance Storm
Consumer rebalances are the #1 cause of production Kafka outages. When a consumer joins or leaves the group, all consumers stop processing and re-assign partitions. If your session.timeout.ms is too low (default 10s), a slow GC pause or network hiccup triggers a rebalance. I've seen a 50-consumer group rebalance every 30 seconds because of a misconfigured heartbeat interval. The fix: set session.timeout.ms to 45s and heartbeat.interval.ms to 15s. Also use cooperative rebalancing (partition.assignment.strategy=org.apache.kafka.clients.consumer.CooperativeStickyAssignor) to reduce the number of full rebalances.
enable.auto.commit=true and your consumer crashes after processing but before the next poll, you'll lose messages. Always commit manually after processing.Monitoring MSK: What AWS Doesn't Tell You
MSK exposes CloudWatch metrics, but the defaults are useless. You need to enable per-broker metrics and set alarms on KafkaDataLogsDiskUsed, CpuUser, and NetworkIn/Out. The critical metric that everyone misses: EstimatedMaxTimeLag. This tells you how far behind the slowest consumer is. Set an alarm at 10 minutes. Also monitor UnderReplicatedPartitions — if it stays above 0 for more than 5 minutes, a broker is struggling. I've seen teams miss a broker failure because they only monitored average metrics. Always look at the max across brokers.
min.insync.replicas is not met.Scaling MSK: Adding Brokers Without Downtime
You can add brokers to an MSK cluster, but it's not instantaneous. The process takes 15-30 minutes and triggers a rolling restart. During this time, clients may experience temporary disconnects. The trick: use a bootstrap string that includes all broker DNS names, and configure your clients with metadata.max.age.ms to refresh metadata every 5 minutes. Also, never scale down — MSK doesn't support it. If you need to reduce capacity, create a new cluster and migrate.
When Not to Use MSK — The Honest Take
MSK is overkill for low-throughput workloads (< 1 MB/s). Use Amazon SQS or Kinesis instead — they're simpler and cheaper. Also, if you need custom Kafka versions or plugins, MSK's version lock-in (only supports certain versions) will frustrate you. For teams that need full control, self-hosted Kafka on EC2 is still viable. But for most production pipelines, MSK's operational savings outweigh the limitations.
The Silent Broker Drop That Killed Our Pipeline
NotEnoughReplicasException and consumers saw lag spike to millions. No alerts from MSK health checks.min.insync.replicas was not met.retention.bytes per topic to a safe limit (e.g., 50 GB) and enabled log.retention.bytes on the cluster. Also increased min.insync.replicas to 2 and default.replication.factor to 3.- Never assume MSK's auto-recovery is instant.
- Always design for temporary broker unavailability with proper
acksand replication settings.
NotEnoughReplicasExceptionmin.insync.replicas config on the topic. 2. Verify number of in-sync replicas with kafka-topics.sh --describe. 3. If a broker is down, wait for MSK to replace it (15-30 min). 4. Temporarily reduce min.insync.replicas to 1 if urgent.kafka-consumer-groups.sh --describe --group <group>. 2. Look for Stable state — if Rebalancing, fix session timeouts. 3. Increase partitions or add more consumers. 4. Check processing logic for blocking calls.CpuUser CloudWatch metric. 2. Identify heavy topics with kafka-topics.sh --describe. 3. Increase partitions to distribute load. 4. Tune producer batch size and compression. 5. Consider adding brokers.aws cloudwatch get-metric-statistics --namespace AWS/Kafka --metric-name CpuUser --dimensions Name=Cluster Name,Value=my-cluster --statistics Maximum --period 60 --start-time $(date -u -d '-5 minutes' +%Y-%m-%dT%H:%M:%SZ)kafka-topics.sh --bootstrap-server $BROKER --describe --topic ordersbatch.size to 65536 and linger.ms to 10. Set acks=1.| File | Command / Code | Purpose |
|---|---|---|
| msk-topic-config.sh | kafka-topics.sh --create \ | Why MSK Isn't Magic |
| OrderProducer.java | public class OrderProducer { | Tuning Producers for Throughput Without Losing Data |
| OrderConsumer.java | public class OrderConsumer { | Consumer Design |
| msk-cloudwatch-alarms.sh | aws cloudwatch put-metric-alarm \ | Monitoring MSK |
| msk-scale-up.sh | aws kafka update-broker-count \ | Scaling MSK |
Key takeaways
min.insync.replicas to replication factor minus 1 to avoid write unavailability during broker failures.EstimatedMaxTimeLag and UnderReplicatedPartitionsInterview Questions on This Topic
How does Amazon MSK handle a broker failure, and what impact does it have on producers and consumers?
min.insync.replicas is not met. Consumers may experience increased latency as they wait for the new broker to catch up.Frequently Asked Questions
20+ years shipping production infrastructure and CI/CD at scale. Everything here is grounded in real deployments.
That's AWS. Mark it forged?
3 min read · try the examples if you haven't