PoppyDB β€” A MongoDB-Compatible In-Memory Server

info

date: 2026-03-11 20:05:00

tags:

creator Stephan BΓΆsebeck

logged in

ADMIN


PoppyDB β€” A MongoDB-Compatible In-Memory Server

PoppyDB β€” A MongoDB-Compatible In-Memory Server

Why "PoppyDB"?

Poppy is the flower that morphine is derived from β€” and Morphium is the German word for morphine. So the name fits perfectly: PoppyDB is the lightweight essence that emerged from the Morphium project.

What used to be buried inside the Morphium monolith as "MorphiumServer" is now a standalone product. But why extract it?

The Problem

Morphium is a MongoDB client for Java. Most users need exactly that: a convenient Java API for MongoDB. However, de.caluga:morphium used to drag along the entire server code β€” including Netty and all its dependencies. That's baggage 90% of users never need.

At the same time, MorphiumServer was more than just a testing tool. It implements the MongoDB Wire Protocol, supports Replica Sets, has its own leader election, and can serve as a full-featured messaging backend. That deserves its own identity.

What Is PoppyDB?

PoppyDB is an in-memory server that speaks the MongoDB Wire Protocol. That means:

  • Any MongoDB client can connect β€” mongosh, PyMongo, the official Java Driver, or of course Morphium
  • No MongoDB setup required β€” no Replica Set to configure, no database to install
  • Starts in milliseconds
  • Perfect for testing, prototyping, and as a lightweight messaging backend

As a Test Backend

The classic use case: unit and integration tests without a real MongoDB. Just add it as a test dependency:

<dependency>
    <groupId>de.caluga</groupId>
    <artifactId>poppydb</artifactId>
    <version>6.2.0</version>
    <scope>test</scope>
</dependency>
PoppyDB server = new PoppyDB(27017);
server.start();

// Any MongoDB client can now connect
MorphiumConfig cfg = new MorphiumConfig("localhost", 27017, "testdb");
Morphium morphium = new Morphium(cfg);

// Run tests...

server.stop();

No Docker containers, no Testcontainers setup, no external infrastructure.

As a Messaging Backend

This might be the most exciting use case. Morphium has a built-in messaging system based on MongoDB Change Streams. With PoppyDB as the backend, you don't need any MongoDB for simple messaging scenarios:

// Start server
PoppyDB server = new PoppyDB(27017);
server.start();

// Two Morphium instances as "microservices"
Morphium sender = new Morphium(new MorphiumConfig("localhost", 27017, "messaging"));
Morphium receiver = new Morphium(new MorphiumConfig("localhost", 27017, "messaging"));

// Start messaging
MorphiumMessaging senderMQ = sender.createMessaging();
MorphiumMessaging receiverMQ = receiver.createMessaging();
receiverMQ.start();

receiverMQ.addListenerForTopic("orders", (mq, msg) -> {
    System.out.println("New order: " + msg.getValue());
    return null;
});

// Send a message
Msg order = new Msg("orders", "new_order", "{orderId: 42}");
senderMQ.sendMessage(order);

That's a full-featured message queue with topics, exclusive delivery, request/response patterns β€” no Kafka, no RabbitMQ, no MongoDB. Just one Java dependency.

Here's the kicker: PoppyDB and Morphium Messaging are optimized for each other. Morphium explicitly detects PoppyDB as its backend and adapts its behavior. At the same time, PoppyDB has server-side optimizations built in that are specifically tailored to Morphium Messaging. With a real MongoDB, messaging has to rely on change streams and polling β€” PoppyDB and Morphium can communicate more directly and efficiently because both sides understand messaging semantics. The result: lower latency and less overhead than using a "real" MongoDB as a messaging backend.

Standalone CLI

PoppyDB can also run as a standalone server:

java  -jar poppydb-6.2.0-cli.jar  --port 27017

This gives you a MongoDB-compatible server that's ready to go immediately. Handy for local development when you don't want to install MongoDB.

What Can PoppyDB Do?

  • MongoDB Wire Protocol β€” compatible with standard MongoDB clients
  • Replica Set Simulation β€” including leader election and failover
  • Change Streams β€” push notifications on data changes
  • Aggregation Pipeline β€” the most important stages are implemented
  • Indexes β€” for fast queries even in in-memory mode
  • Persistence via Snapshots β€” periodic dumps and automatic restore on startup

Persistence: Snapshots

PoppyDB is in-memory, but data doesn't have to be lost. The built-in dump mechanism periodically saves all databases to a directory and automatically restores them on the next startup:

java  -jar poppydb-6.2.0-cli.jar  --port 27017  --dump-dir  /var/poppydb/data  --dump-interval 300

This saves the complete state every 5 minutes. A final dump is written on shutdown, and the data is automatically restored on the next start. Programmatically:

PoppyDB server = new PoppyDB(27017);
server.setDumpDirectory(new File("/var/poppydb/data"));
server.setDumpIntervalMs(300_000)// every 5 minutes
server.start();

// Manual dump at any time
server.dumpNow();

No WAL, no journaling β€” but for development, testing, and messaging scenarios, this is perfectly sufficient.

What Can't PoppyDB Do (Yet)?

Honesty matters: PoppyDB is not a production MongoDB replacement. Not all MongoDB features are implemented, and performance characteristics naturally differ from a disk-based database. Persistence is snapshot-based β€” data can be lost between two dumps.

Migrating from MorphiumServer

If you were using MorphiumServer / MorphiumServerCLI directly:

BeforeAfter
de.caluga.morphium.server.MorphiumServerde.caluga.poppydb.PoppyDB
de.caluga.morphium.server.MorphiumServerCLIde.caluga.poppydb.PoppyDBCLI
morphium-<version>-server-cli.jarpoppydb-<version>-cli.jar
Package de.caluga.morphium.server.*Package de.caluga.poppydb.*

The wire protocol is backward compatible β€” the server sends both poppyDB: true and morphiumServer: true in the hello response.

What's Next

PoppyDB is now a standalone module and can evolve independently from Morphium. Planned improvements include:

  • Better aggregation pipeline support
  • Performance optimizations for large datasets
  • Persistence options beyond snapshots

The source code lives in the Morphium repository on GitHub in the poppydb/ directory.

<dependency>
    <groupId>de.caluga</groupId>
    <artifactId>poppydb</artifactId>
    <version>6.2.0</version>
</dependency>