The License Everyone Panics About, Correctly Read
If you self-host MongoDB Community for your own application, the SSPL almost certainly does not affect you. If you offer MongoDB itself to other people as a service, it absolutely does. That single distinction is the whole licence question, and most of the panic on the internet skips it.
MongoDB Community has been under the Server Side Public License since October 16, 2018. Everything before that was AGPL, and as of September 2026 nothing has changed: LICENSE-Community.txt in the mongodb/mongo repo is still SSPL v1. MongoDB did not switch to be friendly. They did it because cloud vendors were selling MongoDB as a service without contributing back, and the company wanted a piece of that revenue.
What section 13 actually says
Read the trigger instead of the blog posts about the trigger. SSPL section 13 fires “if you make the functionality of the Program or a modified version available to third parties as a service”, and spells out what that means: letting third parties interact with MongoDB’s functionality remotely, or offering a service whose value “entirely or primarily derives from” MongoDB.
If it fires, you owe the “Service Source Code”: MongoDB plus everything you used to offer MongoDB as a service. The licence names them: management software, user interfaces, APIs, automation, monitoring, backup, storage and hosting software.
Three things follow, and they matter more than the vibes:
- Your application is not the Program. A SaaS app that stores its own data in MongoDB is not offering MongoDB’s functionality to third parties. Nobody credible reads section 13 as covering that, and MongoDB’s own marketing has said so repeatedly.
- Internal tooling is not “third parties as a service.” Your employees using your internal dashboard are not third parties interacting with MongoDB remotely.
- The drivers are not SSPL.
pymongo, the Node driver and the Go driver are all Apache 2.0. Importing a MongoDB driver carries no copyleft obligation at all.
Where the real cost sits
The real problems with SSPL aren’t lawsuits, they’re logistics. The OSI never approved it, which means it is not an open source licence by the definition most procurement departments use. Debian, Fedora and Red Hat all dropped MongoDB from their repositories over it. If you work somewhere with a licence allowlist, “not OSI-approved” is a wall you hit at a compliance review, not in court.
And if you really do need to offer MongoDB as a service, or your legal team just wants the ambiguity gone, MongoDB sells the answer: an Enterprise Advanced subscription includes a commercial licence for MongoDB Enterprise Server, self-managed, on your own hardware, no SSPL at all. Atlas is not the only escape hatch, whatever the comparison posts say.
So the options are: keep Community and stay inside section 13, buy Enterprise Advanced, move to Atlas, or swap the engine for something with a boring licence. FerretDB is the interesting version of that last option.
FerretDB: The MongoDB API Without the Legal Migraine
FerretDB is a proxy that speaks fluent MongoDB but runs on Postgres under the hood. FerretDB v1 also had MySQL and SQLite backends, but v2 dropped them. It’s now built around Postgres plus Microsoft’s open-source DocumentDB extension, which adds a native BSON type. It’s like wearing a MongoDB costume while driving a Postgres engine. You get the MongoDB API your app already knows. You do not get a perfect substitute.
What FerretDB Actually Is
FerretDB intercepts MongoDB protocol traffic and translates it into SQL queries against a real relational database. Your app uses the MongoDB driver (pymongo, node-mongo, go-mongo, whatever), but instead of talking to MongoDB, it’s talking to FerretDB, which then talks to Postgres.
FerretDB’s own docs put the bar at MongoDB 5.0: any driver or application compatible with MongoDB 5.0 or later should work against it. Aggregation pipelines, indexes, full-text search with stemming and stop words, TTL indexes and vector search are all in. Multi-document transactions are not. More on that below, because it’s the one gap that will actually stop a migration dead.
The other catch is performance, and here you should be suspicious of anyone quoting you a number, this post included. FerretDB is doing translation work native MongoDB doesn’t have to do, but the cost depends entirely on your query shapes and how well DocumentDB’s BSON indexes match them. Run your own workload against it before you believe anybody’s benchmark, including the vendor’s.
Running FerretDB in Docker Compose
The stack is two containers:
services: postgres: # FerretDB v2 needs Postgres with the DocumentDB extension compiled in. # Plain postgres:17 will NOT work. Pin the full tag: it locks the # Postgres major, the DocumentDB extension version, and the FerretDB # version it was built against. The bare ":17" tag exists but rolls the # extension underneath you. image: ghcr.io/ferretdb/postgres-documentdb:17-0.107.0-ferretdb-2.7.0 environment: POSTGRES_USER: ferretdb_user POSTGRES_PASSWORD: strongpasswordhere POSTGRES_DB: postgres volumes: - postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ferretdb_user -d postgres"] interval: 5s timeout: 5s retries: 5
ferretdb: image: ghcr.io/ferretdb/ferretdb:2.7.0 environment: FERRETDB_POSTGRESQL_URL: "postgres://ferretdb_user:strongpasswordhere@postgres:5432/postgres" ports: - "27017:27017" depends_on: postgres: condition: service_healthy
volumes: postgres_data:Spin it up with docker compose up -d and you’ve got a MongoDB-compatible service running on localhost:27017. Your app connects exactly like it would to real MongoDB, same driver, same connection string format (mongodb://localhost:27017), same API calls.
FerretDB translates the MongoDB wire protocol directly into equivalent Postgres queries, and it all happens behind the scenes.
Real MongoDB vs FerretDB: When Self-Hosting Still Makes Sense
Okay, so when do you actually want to run MongoDB (the real one) on your own servers in 2026?
Use real, self-hosted MongoDB Community if:
- You are running it behind your own application, which is the case for almost every home lab and most companies
- You need multi-document transactions, change streams, or a real replica set with automatic failover
- You need the aggregation and index features FerretDB has not implemented
- Your procurement process does not flag non-OSI licences, or nobody asks
Use MongoDB Enterprise Advanced if:
- You actually do offer MongoDB itself to third parties as a service, which is the one case section 13 fires on
- Your procurement or compliance process requires a commercial licence on paper
- You want the enterprise features (LDAP and Kerberos auth, auditing, encryption at rest, in-memory engine)
Use FerretDB if:
- Your policy forbids non-OSI licences and Apache 2.0 is the requirement, not a preference
- You already run Postgres and want one database engine to back up, monitor and tune
- Your app never opens a transaction, which you can verify by grepping for
withTransactionandstartSession - You want
pg_dump, logical replication and PostGIS sitting next to your document collections
Use Atlas (cloud) if:
- You want somebody else to own backups, failover and patching
- You need full MongoDB feature parity with zero licence conversation
The FerretDB Compatibility Reality Check
FerretDB is not 100% MongoDB, and you don’t have to guess by how much: the project publishes a per-command support table and keeps it current. Read it before you plan anything. What follows is the state of FerretDB 2.7.
What’s supported:
- CRUD (
find,insert,update,delete,findAndModify) aggregate,count,distinct- Index creation and management, single-field and compound
- Full-text search with real text indexes: tokenizing, stop words, stemming, weighting
- Vector search, with the usual similarity metrics, because pgvector is sitting right there
- TTL indexes, single-field only, swept by a background job every 60 seconds
explain,collStats,dbStats,serverStatus,compact,reIndex- User management:
createUser,dropUser,updateUser,usersInfo - The Atlas Data API surface, which real MongoDB only gives you in Atlas
What isn’t:
- Multi-document transactions.
startSessionworks, butcommitTransactionandabortTransactionare both listed as not implemented. If your code callssession.withTransaction(), it will not work. This is the single most important line in this article. bulkWriteas a command (individual writes are fine)- Role management, all of it:
createRole,dropRole,grantRolesToUser,revokeRolesFromUser. You get users, not RBAC. - Capped collections (
convertToCapped,cloneCollectionAsCapped) setParameter,shutdown,killOp,dropConnections,logRotate,profile- Sharding. What you get is Postgres streaming replication, which gives you a read-only replica, not a MongoDB replica set. No
rs.status(), no automatic primary election, no writes to the secondary. - Error messages differ from MongoDB’s, though error names and codes match. Code that string-matches on error text breaks.
- Collection names must be valid UTF-8 where MongoDB tolerates invalid sequences. FerretDB says it will not fix that one.
The practical question is whether your app touches that list. For a document store behind a web app, usually not. For anything that opens a transaction to keep two collections consistent, absolutely yes, and no amount of testing closes that gap.
Testing Before You Commit
Don’t just point your test suite at FerretDB and hope. FerretDB ships a diff-normal mode that makes it a proxy in front of your real MongoDB: every request goes to both engines and it reports the differences between the two responses. That’s a compatibility audit, not a pass/fail.
ferretdb --mode=diff-normal \ --proxy-addr=mongodb://mongo-host:27017 \ --listen-addr=127.0.0.1:27017 \ --postgresql-url=postgres://user:pass@localhost:5432/postgresNow run your application, or your integration suite, against 127.0.0.1:27017 and read the diff output. Errors FerretDB does return are passed straight through to the client, so a hard incompatibility shows up as a failing test rather than a silent behaviour change you discover six months later.
# Once diff-normal comes back clean, run the real stackdocker compose up -dexport MONGO_URL=mongodb://localhost:27017/testdbnpm test # or pytest, go test, whateverMigration Path: MongoDB → FerretDB
If you’re running MongoDB today and want to switch to FerretDB:
The good news is that FerretDB works with MongoDB’s own tooling, so there’s no bespoke migration utility to learn. FerretDB’s docs point you at mongodump/mongorestore and mongoexport/mongoimport directly.
- Audit compatibility first with
diff-normalmode, above. Do this before you touch data. - Dump your MongoDB data with
mongodump - Stand up FerretDB with its DocumentDB-enabled Postgres backend
- Restore the data with
mongorestoreagainst the FerretDB endpoint - Swap your connection string in your app config
- Gradual cutover: send a percentage of traffic to FerretDB, monitor, ramp up
# Export from MongoDBmongodump --uri="mongodb://mongo-host:27017" --out=./dump
# Start FerretDB stackcd ferretdb-compose && docker compose up -d
# Import into FerretDBmongorestore --uri="mongodb://localhost:27017" ./dumpTwo honest caveats on timing. mongorestore speed is a function of dataset size, and inserting through the wire protocol into DocumentDB is slower than restoring into MongoDB, so budget by the gigabyte rather than by the hour. And plan the rollback explicitly: keep the original MongoDB instance running read-only until you’re confident, because there’s no mongorestore path back out of Postgres that preserves anything FerretDB stored differently.
The Postgres Elephant in the Room
If you’re running FerretDB, you’re really running Postgres. So why not just use Postgres directly?
Fair question. The answer is that you don’t have to rewrite your app. Your Python code that uses pymongo works unchanged. Your Node.js Mongoose schemas need no changes. Your Go mongo-go-driver code is untouched. You keep your codebase and swap the licence underneath it.
But if you’re starting fresh, using Postgres directly is simpler: one fewer moving part, one fewer translation layer, no per-command compatibility table to check, and transactions that actually work. The time saved not rewriting a data layer is only worth it when there’s a data layer to save.
PostgreSQL: The Alternative You Should Consider
Postgres has been shipping since 1996 and is boring in the best sense. It’s also open source in the way that clears a compliance review, which SSPL is not.
If you’re picking a database for a new self-hosted project in 2026, Postgres should be your first instinct. It handles JSON first-class (JSONB), it has great driver support, and the entire ecosystem of DevOps tooling assumes you’re using Postgres anyway.
The only reason to pick MongoDB-shaped databases (real Mongo or FerretDB) is if you’re committed to document-oriented modeling or you’re migrating existing code.
Decision Tree: Which Do I Pick?
Work down this list:
Self-hosting MongoDB behind your own app, and your code uses transactions? → Stay on MongoDB Community. Section 13 does not fire on you, and FerretDB cannot run your code.
Self-hosting MongoDB behind your own app, no transactions, and you want off SSPL for procurement reasons? → FerretDB. Audit with diff-normal first.
Building new and you need document storage? → Postgres with JSONB. You are one docker compose up from a database that does everything above and commits properly.
Actually offering MongoDB as a service to third parties? → Section 13 fires. Buy Enterprise Advanced for the commercial licence, or move to Atlas. Don’t self-host Community and hope.
Compliance team blocks non-OSI licences? → FerretDB (Apache 2.0), plain Postgres (PostgreSQL licence), or Enterprise Advanced.
Solo hobby project? → MongoDB Community. You are not the reason SSPL exists.
The Bottom Line
SSPL is not a trap laid for you. It’s a trap laid for AWS, and the collateral damage is that MongoDB stopped being an OSI-approved licence and fell out of the distro repositories. For most self-hosters the practical consequence is a procurement conversation, not a lawsuit.
If you want a MongoDB-shaped API with a licence nobody argues about, FerretDB 2.7 on Postgres is a real option, Apache 2.0, with the DocumentDB extension underneath it under MIT. Check the command support table for transactions and role management before you commit, because those are the two gaps that stop migrations.
If you’re not married to the document model, Postgres alone will serve you better. If you are actually offering MongoDB itself as a service, pay for Enterprise Advanced and stop worrying about it. Your 2 AM self will thank you.
Common Questions
Does the SSPL apply to my app if I just store data in MongoDB?
No. SSPL section 13 fires only when you make MongoDB’s own functionality available to third parties as a service. A web app that stores its data in MongoDB is not offering MongoDB to anyone, and the drivers you import (pymongo, the Node and Go drivers) are Apache 2.0 with no copyleft at all.
Can I self-host MongoDB legally without the SSPL?
Yes. A MongoDB Enterprise Advanced subscription includes a commercial licence for MongoDB Enterprise Server, self-managed on your own hardware, with no SSPL obligations. Atlas is not the only alternative to Community, despite what most comparison posts say. Pricing is quote-based, so contact sales.
Does FerretDB support MongoDB transactions?
No. As of FerretDB 2.7, startSession works but commitTransaction and abortTransaction are both unimplemented, so session.withTransaction() fails. If your application relies on multi-document transactions, FerretDB is not a drop-in replacement and no configuration option changes that.
Is FerretDB slower than MongoDB?
Sometimes, by an amount that depends entirely on your query shapes. FerretDB translates the MongoDB wire protocol into Postgres operations against the DocumentDB extension, which adds work MongoDB skips. Distrust every published benchmark, this article included, and measure your own workload in diff-normal mode first.
What happened to FerretDB’s MySQL and SQLite backends?
FerretDB v1 supported SQLite and had experimental MySQL support. Version 2 dropped both and rebuilt around Postgres plus Microsoft’s open-source DocumentDB extension, which adds a native BSON type. If you were running a v1 SQLite deployment, migrating to v2 means moving to Postgres.