Skip to content

Widhian Bramantya

coding is an art form

Menu
  • About Me
Menu
nats

Ensuring Message Ordering in NATS: A Kafka-like Approach

Posted on September 6, 2025September 6, 2025 by admin

Rebalancing for Dynamic Scaling

The system implements automatic rebalancing when consumers join or leave:

  1. Consumer Join: Existing consumers voluntarily release partitions to accommodate new consumers
  2. Consumer Leave: Other consumers claim released partitions to maintain processing
  3. Fair Distribution: Partitions are redistributed evenly among available consumers

This approach ensures no message loss during scaling events while maintaining ordering guarantees.

Key Implementation Details

1. Message Deduplication

Using JetStream’s message ID feature prevents duplicate processing:

ack, err := js.Publish(pubCtx, subject, b, jetstream.WithMsgID(idKey))

2. Consumer Durability

Durable consumers ensure message delivery even when consumers restart:

cfg := &nats.ConsumerConfig{
    Durable:        durable,
    FilterSubject:  filterSubject,
    AckPolicy:      nats.AckExplicitPolicy,
    AckWait:        2 * time.Minute,
    MaxAckPending:  512,
    ReplayPolicy:   nats.ReplayInstantPolicy,
}

3. Lease Management

The lease store provides atomic operations for claiming, renewing, and releasing partitions:

// Try to claim a partition
info, err := ls.TryClaim(pid, app, leaseTTL)
// Renew an existing lease
info, err := ls.Renew(pid, app, prevRev, leaseTTL)
// Release a partition when shutting down
err = ls.Release(pid, app)

Failover and Recovery Mechanisms

The system handles various failure scenarios gracefully:

  1. Graceful Shutdown: Consumers release partitions before terminating
  2. Forced Termination: Leases expire automatically, allowing other consumers to claim partitions
  3. Network Partitions: Heartbeat mechanisms detect disconnected consumers
  4. Process Failures: Expired leases enable fast failover to other consumers

Performance Considerations

This approach provides several benefits:

  • Maintained Ordering: Messages with the same key are processed in order
  • Scalability: Consumers can be added or removed dynamically
  • Fault Tolerance: Automatic recovery from failures
  • Resource Efficiency: Partitions are evenly distributed among consumers

However, there are trade-offs:

  • Partition Count: Must be planned based on expected throughput
  • Lease Overhead: Coordination requires additional storage and network operations
  • Complexity: More complex than simple queue-based processing
See also  Publish–Subscribe in NATS: Simple and Powerful Messaging

Configuration Parameters

Key configuration parameters affect system behavior:

# Partitioning
PARTITIONS=8

# Lease management
LEASE_TTL_SEC=5
HEARTBEAT_SEC=2

# Consumer behavior
FETCH_BATCH=10

These values balance between responsiveness and system overhead.

Monitoring and Observability

The system includes monitoring capabilities:

  • Process Management: Track active consumers and their assigned partitions
  • Lease Visualization: View current partition ownership
  • Message Flow: Monitor stream messages and processing status

Conclusion

This implementation demonstrates how NATS JetStream can achieve Kafka-like message ordering through careful architectural design. By combining partitioned subjects, consistent hashing, lease-based coordination, and automatic rebalancing, we can build systems that maintain strict ordering guarantees while remaining scalable and fault-tolerant.

The key advantages of this approach include:

  • Native NATS ecosystem integration
  • Dynamic scaling capabilities
  • Fast failover mechanisms
  • Strong ordering guarantees within partitions
  • No external dependencies beyond NATS

For applications requiring strict message ordering with the performance and simplicity of NATS, this pattern provides an excellent alternative to traditional message queue solutions. For reference, you can see the example directly here

Pages: 1 2 3 4
Category: NATS

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Linkedin

Widhian Bramantya

Recent Posts

  • Log Management at Scale: Integrating Elasticsearch with Beats, Logstash, and Kibana
  • Index Lifecycle Management (ILM) in Elasticsearch: Automatic Data Control Made Simple
  • Blue-Green Deployment in Elasticsearch: Safe Reindexing and Zero-Downtime Upgrades
  • Maintaining Super Large Datasets in Elasticsearch
  • Elasticsearch Best Practices for Beginners
  • Implementing the Outbox Pattern with Debezium
  • Production-Grade Debezium Connector with Kafka (Postgres Outbox Example – E-Commerce Orders)
  • Connecting Debezium with Kafka for Real-Time Streaming
  • Debezium Architecture – How It Works and Core Components
  • What is Debezium? – An Introduction to Change Data Capture
  • Offset Management and Consumer Groups in Kafka
  • Partitions, Replication, and Fault Tolerance in Kafka
  • Delivery Semantics in Kafka: At Most Once, At Least Once, Exactly Once
  • Producers and Consumers: How Data Flows in Kafka
  • Kafka Architecture Explained: Brokers, Topics, Partitions, and Offsets
  • Getting Started with Apache Kafka: Core Concepts and Use Cases
  • Security Best Practices for RabbitMQ in Production
  • Understanding RabbitMQ Virtual Hosts (vhosts) and Their Uses
  • RabbitMQ Performance Tuning: Optimizing Throughput and Latency
  • High Availability in RabbitMQ: Clustering and Mirrored Queues Explained

Recent Comments

  1. Playing with VPC AWS (Part 2) – Widhian's Blog on Playing with VPC AWS (Part 1): VPC, Subnet, Internet Gateway, Route Table, NAT, and Security Group
  2. Basic Concept of ElasticSearch (Part 3): Translog, Flush, and Refresh – Widhian's Blog on Basic Concept of ElasticSearch (Part 1): Introduction
  3. Basic Concept of ElasticSearch (Part 2): Architectural Perspective – Widhian's Blog on Basic Concept of ElasticSearch (Part 3): Translog, Flush, and Refresh
  4. Basic Concept of ElasticSearch (Part 3): Translog, Flush, and Refresh – Widhian's Blog on Basic Concept of ElasticSearch (Part 2): Architectural Perspective
  5. Basic Concept of ElasticSearch (Part 1): Introduction – Widhian's Blog on Basic Concept of ElasticSearch (Part 2): Architectural Perspective

Archives

  • October 2025
  • September 2025
  • August 2025
  • November 2021
  • October 2021
  • August 2021
  • July 2021
  • June 2021
  • March 2021
  • January 2021

Categories

  • Debezium
  • Devops
  • ElasticSearch
  • Golang
  • Kafka
  • Lua
  • NATS
  • Programming
  • RabbitMQ
  • Redis
  • VPC
© 2025 Widhian Bramantya | Powered by Minimalist Blog WordPress Theme