info
date: 2026-03-11 20:05:00
tags:
creator Stephan BΓΆsebeck
logged in
ADMIN
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:
<groupId>de.caluga</groupId>
<artifactId>poppydb</artifactId>
<version>6.2.0</version>
<scope>test</scope>
</dependency>
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:
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:
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:
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:
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:
| Before | After |
|---|---|
de.caluga.morphium.server.MorphiumServer | de.caluga.poppydb.PoppyDB |
de.caluga.morphium.server.MorphiumServerCLI | de.caluga.poppydb.PoppyDBCLI |
morphium-<version>-server-cli.jar | poppydb-<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.
<groupId>de.caluga</groupId>
<artifactId>poppydb</artifactId>
<version>6.2.0</version>
</dependency>