Skip to main content

Migration Guide

PlugPort is designed as a decentralised drop-in replacement for traditional databases, accepting connections from MongoDB, PostgreSQL, MySQL, Redis, and SQLite clients. This guide covers migration paths from every supported protocol.

Migration Strategies

StrategyCode ChangesBest For
Wire ProtocolZeroApps using mongosh, pymongo, mongo-go-driver
SDK Swap2 linesApps willing to use PlugPort SDK for extra features
GradualIncrementalLarge codebases migrating collection by collection

Migrating from MongoDB

Strategy 1: Wire Protocol (Zero Code Changes)

The simplest path. PlugPort speaks the MongoDB wire protocol on port 27017. Simply point your existing MongoDB URI to the PlugPort server.

Before

# Environment variable
MONGODB_URI=mongodb://mongo-server:27017/myapp

After

# Just change the host
MONGODB_URI=mongodb://plugport-server:27017/myapp

That's it. Your existing pymongo, mongo-go-driver, or mongosh code connects directly - no library changes needed.

Supported Wire Protocol Commands

CommandStatusNotes
hello / isMaster✅ SupportedFull handshake
ping✅ Supported
insert✅ SupportedSingle and batch
find✅ SupportedFilter, sort, projection, limit, skip
update✅ Supported$set operator
delete✅ SupportedSingle and multi
createIndexes✅ SupportedSingle-field indexes
listCollections✅ Supported
count✅ Supported
distinct✅ Supported
aggregate✅ SupportedFull pipeline: $match, $lookup, $project, $sort, $limit, $skip, $unwind, $count
transactions⚠️ Best-EffortBuffered writes, sequential flush on commit, discard on abort
$lookup✅ SupportedCross-collection joins via localField / foreignField

Strategy 2: SDK Swap (2-Line Change)

For applications that want to use the PlugPort SDK directly, the migration is exactly 2 lines of code.

Node.js

- import { MongoClient } from 'mongodb';
+ import { PlugPortClient } from '@plugport/sdk';

- const client = await MongoClient.connect('mongodb://localhost:27017');
+ const client = await PlugPortClient.connect('http://localhost:8080');

// Everything below is IDENTICAL
const db = client.db('myapp');
const users = db.collection('users');

await users.insertOne({ name: 'Alice', email: 'alice@example.com' });
const docs = await users.find({ age: { $gte: 25 } });
await users.updateOne({ name: 'Alice' }, { $set: { age: 31 } });
await users.createIndex('email', { unique: true });
await client.close();

Python

- from pymongo import MongoClient
+ from plugport import PlugPortClient

- client = MongoClient("mongodb://localhost:27017")
+ client = PlugPortClient("http://localhost:8080")

# Everything below is IDENTICAL
db = client["myapp"]
users = db["users"]

users.insert_one({"name": "Alice", "email": "alice@example.com"})
docs = users.find({"age": {"$gte": 25}})
users.update_one({"name": "Alice"}, {"$set": {"age": 31}})

Go

- import "go.mongodb.org/mongo-driver/mongo"
+ import plugport "github.com/plugport/plugport-go"

- client, _ := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
+ client, _ := plugport.Connect("http://localhost:8080")

// Everything below is IDENTICAL
coll := client.Database("myapp").Collection("users")
coll.InsertOne(ctx, map[string]interface{}{"name": "Alice"})

Strategy 3: Gradual Migration

For large codebases, migrate one collection at a time.

Step 1: Run Both Databases

# MongoDB continues running on 27017
# PlugPort runs on different ports
HTTP_PORT=8080 WIRE_PORT=27018 pnpm --filter @plugport/server dev

Step 2: Migrate Data with the CLI

# Export from MongoDB
mongoexport --collection=users --out=users.json

# Import into PlugPort
plugport migrate --file users.json --collection users

Step 3: Switch Connections Per Collection

// Use a factory to decide which driver to use per collection
function getCollection(name: string) {
const migratedCollections = ['users', 'products'];

if (migratedCollections.includes(name)) {
return plugportDb.collection(name); // PlugPort
}
return mongoDb.collection(name); // Legacy MongoDB
}

Step 4: After Full Migration

Remove the MongoDB dependency entirely.


Data Format Compatibility

What Maps Directly

MongoDB FeaturePlugPort Support
JSON documents✅ Full
_id field (ObjectId)✅ Full (24-char hex)
Nested objects✅ Full
Arrays✅ Full
BSON types✅ Via wire protocol
Dot notation in queries⚠️ Top-level fields only (MVP)
$set operator✅ Full
$gt/$lt/$gte/$lte✅ Full
$in/$eq/$ne✅ Full
$and✅ Full
$or✅ Full
$regex❌ Roadmap
Sort✅ Full
Projection (include/exclude)✅ Full
Skip/Limit✅ Full
Single-field indexes✅ Full
Compound indexes❌ Roadmap
TTL indexes❌ Roadmap
Unique constraints✅ Full
Transactions⚠️ Best-Effort (buffered writes, not atomic)

ObjectId Format

MongoDB uses BSON ObjectId (12 bytes). PlugPort generates 24-character hex strings in the same format:

| timestamp | random |
| 8 chars | 16 chars |
|-------------|--------------|
67b2a1f0 a1b2c3d4e5f6a7b8

Both are compatible for querying and sorting by insertion order.


Cost Considerations

Development (Free)

In dev mode, PlugPort uses an in-memory store. No blockchain interaction, no gas fees.

Production (MON Tokens)

When connected to MonadDb (production):

Operation TypeOn-Chain?Cost
Reads (find, findOne, count)No (RPC call)Free
Writes (insert, update, delete)Yes (transaction)MON gas fee
Index operationsYes (KV writes)MON gas fee
tip

The PlugPort server handles all blockchain interaction. Your application code never needs to manage wallets or sign transactions. Fund the server's wallet and it handles the rest.


Troubleshooting MongoDB Migration

"No such command" errors via wire protocol

Some advanced MongoDB commands are not yet supported. Check the Wire Protocol Reference for the full list.

Duplicate key errors after migration

If your data has documents with the same _id, the import will fail. De-duplicate before importing:

# Remove duplicate lines from the export
sort -u users.json > users_dedup.json
plugport migrate --file users_dedup.json --collection users

Performance differences

PlugPort's query planner currently optimizes for single-field index scans. Complex multi-field queries fall back to collection scans. Create indexes on your most-queried fields for best performance.


Migrating from PostgreSQL / MySQL

PlugPort's SQL Translation Layer lets you connect with psql, mysql, or any PostgreSQL/MySQL client library and use familiar SQL syntax.

Enable the Protocol

# In .env
PG_ENABLED=true # PostgreSQL on port 5432
MYSQL_ENABLED=true # MySQL on port 3306

Connect with Your Existing Client

# PostgreSQL
psql -h localhost -p 5432

# MySQL
mysql -h localhost -P 3306

Supported SQL Statements

StatementStatusNotes
SELECT with WHERE, ORDER BY, LIMIT, OFFSET✅ SupportedTranslates to document find
INSERT INTO ... VALUES✅ SupportedSingle and batch
UPDATE ... SET ... WHERE✅ SupportedTranslates to updateOne/updateMany
DELETE FROM ... WHERE✅ SupportedTranslates to deleteOne/deleteMany
CREATE INDEX✅ SupportedSingle-field indexes
DROP INDEX✅ Supported
CREATE TABLE✅ SupportedCreates a collection
DROP TABLE✅ SupportedDrops a collection
SHOW TABLES / SHOW DATABASES✅ Supported
DESCRIBE / DESC✅ Supported
JOIN (INNER, LEFT, RIGHT, CROSS)✅ SupportedVia JoinEngine
COUNT, SUM, AVG, MIN, MAX✅ SupportedAggregation functions
BEGIN / COMMIT / ROLLBACK⚠️ Best-EffortBuffered writes, sequential flush on commit
PRAGMA⚠️ IgnoredSQLite compat

HTTP API Alternative

You can also execute SQL via the HTTP API:

curl -X POST http://localhost:8080/api/v1/sql \
-H "Content-Type: application/json" \
-d '{"query": "SELECT * FROM users WHERE age >= 25 ORDER BY age DESC LIMIT 10"}'

Key Differences from Native PostgreSQL/MySQL

  • Best-effort transactionsBEGIN/COMMIT buffer writes and flush sequentially (not atomic rollback)
  • No stored procedures or triggers — Not supported
  • No foreign keys — Use the JoinEngine for cross-collection queries
  • Document-based storage — Tables are collections of JSON documents internally
  • Schema-free — No need for ALTER TABLE; documents can have varying fields

Migrating from Redis

PlugPort implements the RESP protocol and supports 50+ Redis commands. Connect with redis-cli or any Redis client library.

Enable the Protocol

# In .env
REDIS_ENABLED=true # Redis on port 6379

Connect

redis-cli -h localhost -p 6379

Supported Command Groups

CategoryCommandsNotes
StringGET, SET, SETNX, MGET, MSET, INCR, DECR, APPEND, STRLEN✅ Full
HashHSET, HGET, HDEL, HGETALL, HKEYS, HVALS, HLEN, HEXISTS✅ Full
ListLPUSH, RPUSH, LPOP, RPOP, LRANGE, LLEN✅ Full
SetSADD, SREM, SMEMBERS, SISMEMBER, SCARD✅ Full
KeysDEL, EXISTS, KEYS, TYPE, EXPIRE, PEXPIRE, TTL, PTTL, PERSIST✅ Full
Pub/SubPUBLISH, SUBSCRIBE, UNSUBSCRIBE, PSUBSCRIBE✅ Full (SSE via HTTP)
ServerPING, ECHO, INFO, DBSIZE, FLUSHDB, FLUSHALL, SELECT, AUTH, QUIT✅ Full

HTTP API Alternative

# Execute Redis commands via HTTP
curl -X POST http://localhost:8080/api/v1/redis \
-H "Content-Type: application/json" \
-d '{"command": ["SET", "mykey", "myvalue"]}'

# Subscribe to Pub/Sub via SSE
curl -N "http://localhost:8080/api/v1/redis/stream?channels=chat,notifications"

Key Differences from Native Redis

  • Persistent storage — Data is backed by MonadDb (or in-memory in dev), not Redis's AOF/RDB
  • No Lua scriptingEVAL and EVALSHA are not supported
  • No cluster mode — Single-node only
  • No streamsXADD/XREAD not supported; use Pub/Sub instead

Migrating from SQLite

The @plugport/sqlite-compat package provides a drop-in replacement for better-sqlite3, letting SQLite-based applications use PlugPort as a backend.

Installation

npm install @plugport/sqlite-compat

Usage

// Before: import Database from 'better-sqlite3';
import Database from '@plugport/sqlite-compat';

const db = new Database(':memory:');
db.exec('CREATE TABLE users (name TEXT, age INTEGER)');
db.exec("INSERT INTO users VALUES ('Alice', 30)");
const rows = db.prepare('SELECT * FROM users WHERE age >= ?').all(25);

This routes all SQL operations through PlugPort's SQL Translation Layer, giving you the same API surface as better-sqlite3 while storing data in PlugPort's document store.