DEV Community

Stephen Maina
Stephen Maina

Posted on

JayNats: The Future of Message Brokers

Getting Started with JayNats: Zero-Copy Real-time CDC in Minutes

A tutorial-style blog post showcasing JayNats as a zero-copy, low-latency messaging broker with seamless CDC


If you're building real-time applications, you've probably dealt with messaging brokers and change data capture (CDC) separately. Kafka for events, Debezium for CDC, Redis for caching—the modern microservices architecture is a symphony of moving parts.

But what if I told you that you could have zero-copy, low-latency messaging with type-safe CDC in a single Java library?

Enter JayNats - a production-ready messaging broker built with Java's Foreign Function & Memory API, optimized for sub-microsecond latency with zero-copy operations. It just so happens to ship with CDC out of the box.

What is JayNats?

JayNats is, first and foremost, a zero-copy, low-latency messaging broker powered by Java's new FFM API. While it ships with CDC capabilities as a showcase feature, its core mission is providing the fastest, most efficient message passing in the JVM ecosystem.

Key Features

  • Zero-copy operations with FFM for unparalleled performance
  • Sub-microsecond latency for message processing
  • Built-in CDC with automatic schema discovery
  • Type-safe JOOQ Records - no JSON, no manual parsing
  • Simple, consistent API across all use cases
  • Production-ready with real-time demo at https://akilisha.com

Beyond CDC: JayNats as a Messaging Broker

Before diving into CDC, let's see JayNats in its primary role: zero-copy messaging. The beauty is the API remains consistent whether you're doing simple pub/sub or advanced CDC.

Event-Driven Architecture

import com.jaynats.stream.MessageBroker;
import com.jaynats.stream.SimpleMessageBroker;

MessageBroker broker = new SimpleMessageBroker();
broker.createTopic("user-events", 1).get();

// Publisher
broker.publish("user-events", "User registered: john@example.com".getBytes()).get();

// Subscribers
broker.subscribe("user-events", message -> {
    System.out.println("📧 " + new String(message.data()));
});
Enter fullscreen mode Exit fullscreen mode

Microservices Communication

// Service A: Order Service
MessageBroker broker = new SimpleMessageBroker();
broker.createTopic("orders", 1).get();
broker.publish("orders", orderJson.getBytes()).get();

// Service B: Payment Service (in a different process)
broker.subscribe("orders", message -> {
    Order order = parseOrder(message.data());
    processPayment(order);
});
Enter fullscreen mode Exit fullscreen mode

Pub/Sub Patterns

// Multiple subscribers to the same topic
broker.subscribe("notifications", message -> {
    emailService.send(new String(message.data()));
});

broker.subscribe("notifications", message -> {
    smsService.send(new String(message.data()));
});

// Publish once, fan out to all
broker.publish("notifications", "User logged in".getBytes()).get();
Enter fullscreen mode Exit fullscreen mode

Real-Time Data Streaming

// High-frequency sensor data with zero-copy performance
broker.createTopic("sensor-data", 1).get();

void onSensorReading(double temperature) {
    byte[] data = serialize(temperature);
    broker.publish("sensor-data", data).get();  // Sub-microsecond latency!
}

broker.subscribe("sensor-data", message -> {
    double temp = deserialize(message.data());
    updateDashboard(temp);
});
Enter fullscreen mode Exit fullscreen mode

Notice the pattern? Simple, consistent, powerful. The same API works for everything.

The Live Demo

Before we dive into the code, check out the live demo at https://akilisha.com. Connect your PostgreSQL database and watch changes appear in real-time with type-safe, zero-copy event processing!

Getting Started - It's Actually This Simple

The beauty of JayNats is in its simplicity. For CDC, you simply provide your JDBC credentials. That's it. Schema discovery, model generation, trigger creation, and type-safe event mapping are all handled automatically by the library.

Step 1: Add Dependencies

Gradle:

dependencies {
    implementation 'com.akilisha.oss:jaynats-stream:1.0.0'
    implementation 'com.akilisha.oss:jaynats-stream-cdc:1.0.0'
}
Enter fullscreen mode Exit fullscreen mode

Maven:

<dependency>
    <groupId>com.akilisha.oss</groupId>
    <artifactId>jaynats-stream</artifactId>
    <version>1.0.0</version>
</dependency>
<dependency>
    <groupId>com.akilisha.oss</groupId>
    <artifactId>jaynats-stream-cdc</artifactId>
    <version>1.0.0</version>
</dependency>
Enter fullscreen mode Exit fullscreen mode

Or clone the repository from GitHub to build locally.

Step 2: Write Some Code

import com.jaynats.stream.cdc.CDCManager;
import com.jaynats.stream.cdc.generated.tables.records.UsersRecord;

public class RealTimeApp {
    public static void main(String[] args) {
        // Just provide your database URL
        CDCManager cdc = new CDCManager(
            "jdbc:postgresql://localhost:5432/mydb",
            "output/models"
        );

        // Start CDC - the library handles EVERYTHING
        try {
            cdc.startCDC("users", "orders").get();
            System.out.println("✅ CDC started! Schema discovered, models generated, ready to go!");

            // Subscribe with type-safe JOOQ Records
            cdc.subscribeToTableTyped("users", UsersRecord.class, event -> {
                UsersRecord user = event.getData();  // ← Typed JOOQ Record!
                System.out.println("📧 Email: " + user.getEmail());
                System.out.println("👤 Name: " + user.getName());
                // Full IDE autocomplete, compile-time safety!
            });

            // Or use the flexible API for JSON access
            cdc.subscribeToTable("orders", event -> {
                String json = event.getJsonData();  // ← Raw JSON available too
                System.out.println("📦 Order: " + json);
            });

            // Keep running
            Thread.sleep(Long.MAX_VALUE);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

That's it! No manual triggers. No SQL setup. No schema management. Just JDBC credentials.

What Happens Under the Hood

When you call startCDC("users", "orders"), JayNats:

  1. Connects to your PostgreSQL database
  2. Discovers the schema for the specified tables
  3. Generates JOOQ model classes (UsersRecord, OrdersRecord, etc.)
  4. Creates database triggers automatically
  5. Sets up real-time LISTEN/NOTIFY connections
  6. Maps events to typed JOOQ Records

All transparently. Zero manual work.

Type Safety Out of the Box

The real magic is in the type safety. No more parsing JSON strings:

// Before (manual JSON parsing)
cdc.subscribeToTable("users", event -> {
    String json = event.getJsonData();
    JSONObject obj = new JSONObject(json);
    String email = obj.getString("email");  // 😰 Runtime error prone
});

// After (JOOQ Records)
cdc.subscribeToTableTyped("users", UsersRecord.class, event -> {
    UsersRecord user = event.getData();  // ← Strongly typed!
    String email = user.getEmail();      // ← IDE autocomplete!
    Integer id = user.getId();           // ← Compile-time type checking!
});  // 😎 Refactoring-safe, validation at compile time
Enter fullscreen mode Exit fullscreen mode

Streaming to the Live Demo

Want to see your database changes on https://akilisha.com in real-time?

Quick Start

# Build the CDC CLI
./gradlew :jaynats-stream-cdc:build

# Run it
java -jar jaynats-stream-cdc/build/libs/jaynats-stream-cdc-1.0.0.jar \
  --url jdbc:postgresql://localhost:5432/mydb \
  --target https://akilisha.com
Enter fullscreen mode Exit fullscreen mode

Visit https://akilisha.com, start the demo, and your database changes appear in real-time with zero-copy performance!

Why JayNats?

🚀 Zero-Copy Performance

  • Java FFM API for zero-copy memory operations
  • Sub-microsecond latency for message processing
  • Virtual threads for massive concurrency

🎯 Intelligent, Self-Aware

  • Automatic schema discovery - just provide credentials
  • Zero configuration - it figures out what to do
  • Type-safe by default - JOOQ Records everywhere

🏗️ Production-Ready

  • Single JVM process - no external dependencies
  • Modern Java 23 with latest features
  • Live demo at https://akilisha.com

🎨 Consistent API Across Use Cases

The same simple API works for everything:

// Standalone messaging
broker.publish("events", data);
broker.subscribe("events", handler);

// CDC (with zero-copy underneath)
cdc.startCDC("users", "orders");
cdc.subscribeToTableTyped("users", UsersRecord.class, handler);
Enter fullscreen mode Exit fullscreen mode

Whether you're building event-driven architectures, microservices communication, or real-time database synchronization, JayNats provides the same intuitive, consistent experience. No learning curve when switching between use cases.

Advanced Use Cases

Real-time Analytics

cdc.subscribeToTableTyped("orders", OrdersRecord.class, event -> {
    OrdersRecord order = event.getData();  // ← Typed!
    updateDashboard(order.getAmount(), order.getCustomerId());
});
Enter fullscreen mode Exit fullscreen mode

Event Sourcing

cdc.subscribeToAllChanges(event -> {
    eventStore.append(event);  // ← Type-safe event stream
});
Enter fullscreen mode Exit fullscreen mode

Microservices Sync

cdc.subscribeToTableTyped("users", UsersRecord.class, event -> {
    UsersRecord user = event.getData();  // ← Zero JSON conversion!
    distributedCache.put(user.getId(), user);
});
Enter fullscreen mode Exit fullscreen mode

The Philosophy

JayNats is intelligent and self-aware. You shouldn't have to:

  • ❌ Manually create triggers
  • ❌ Write SQL procedures
  • ❌ Parse JSON strings
  • ❌ Manage schema manually
  • ❌ Learn different APIs for different use cases

You just provide credentials for CDC or create a broker for messaging. JayNats handles the rest, delivering typed, zero-copy events with sub-microsecond latency and a consistent, intuitive API across all use cases.

From simple pub/sub to complex CDC, the same beautiful simplicity throughout.

Next Steps

  1. Try the live demo: https://akilisha.com
  2. Check out the code: GitHub
  3. Explore examples: Clone and check jaynats-examples module

JayNats: Zero-copy messaging with intelligent CDC. Just add credentials. 🚀

For the latest updates and contributions, visit GitHub

Top comments (0)