Scaling Without Limits: Transitioning to FerretDB and PostgreSQL for Enterprise MongoDB Workloads
Introduction: The Open-Source Database Dilemma
In the modern enterprise landscape, architectural agility and cost efficiency are paramount. For years, document databases like MongoDB have been the go-to choice for developers requiring flexible schemas and rapid prototyping. However, MongoDB's transition to the Server Side Public License (SSPL) in 2018 fundamentally altered the risk landscape for businesses. The SSPL is not recognized as an open-source license by the Open Source Initiative (OSI), creating legal and financial compliance headaches for organizations aiming to maintain true open-source stacks or offer managed services.
Enter FerretDB. FerretDB serves as an open-source, drop-in replacement for MongoDB by translating MongoDB wire protocol queries into standard SQL. By using PostgreSQL as its backend storage engine, FerretDB enables organizations to retain their existing MongoDB application code, drivers, and tools while leveraging the reliability, security, and truly open-source nature of PostgreSQL. This article provides a comprehensive, technical guide to configuring FerretDB with PostgreSQL to run your document-based workloads without commercial licensing constraints.
---Why Combine FerretDB with PostgreSQL?
Before diving into the configuration, it is essential to understand why this specific stack represents a robust alternative for production environments. By decoupling the database interface from the storage layer, businesses gain several strategic advantages:
- True Open-Source Compliance: FerretDB is licensed under the Apache 2.0 license, and PostgreSQL uses the permissive PostgreSQL License. This guarantees immunity from sudden licensing changes.
- Leveraging PostgreSQL Ecosystem: PostgreSQL is renowned for its ACID compliance, advanced indexing, and rock-solid reliability. By using it as a backend, you inherit enterprise-grade features like point-in-time recovery (PITR), robust replication, and a massive community-driven ecosystem.
- No Application Rewrites: Because FerretDB acts as a proxy that understands the MongoDB wire protocol, your development teams can continue using standard MongoDB drivers (e.g., Mongoose, PyMongo) without rewriting a single line of business logic.
- Unified Database Strategy: Instead of managing separate operational silos for relational and document data, operations teams can consolidate infrastructure onto PostgreSQL, simplifying monitoring, backups, and maintenance.
Architectural Overview
The architecture consists of three core components working in tandem:
- The Application Layer: Your existing microservices or applications configured with standard MongoDB connection strings.
- FerretDB (The Translation Layer): A stateless proxy service that listens on the default MongoDB port (27017), parses BSON commands, and converts them to equivalent SQL queries.
- PostgreSQL (The Storage Layer): The relational database where collections are stored natively as tables, often utilizing the highly optimized
jsonbdata type to handle unstructured document schemas.
Note: Because FerretDB is stateless, it can be scaled horizontally behind a load balancer to handle high-concurrency connection demands, while PostgreSQL manages state and data persistence.---
Prerequisites and Environment Setup
To successfully deploy this stack, ensure your environment meets the following baseline requirements:
- A Linux-based environment (Ubuntu 22.04 LTS or later recommended) or Docker installed.
- PostgreSQL 14 or higher (PostgreSQL 15+ is highly recommended for improved JSON processing performance).
- Network connectivity between the application, FerretDB proxy, and PostgreSQL instance.
Step-by-Step Configuration Guide
While FerretDB can be installed via binaries or packages, deploying via Docker Compose provides the most isolated, repeatable, and production-adjacent setup. Below is the step-by-step process to configure the stack.
Step 1: Preparing the PostgreSQL Database
First, ensure your PostgreSQL instance is ready to receive connections. If you are using a self-hosted PostgreSQL instance, you need to create a dedicated database and user for FerretDB:
CREATE USER ferret_user WITH PASSWORD 'SecurePassword123';
CREATE DATABASE ferret_db OWNER ferret_user;Ensure that your pg_hba.conf is configured to allow MD5 or scram-sha-256 authentication from the host where FerretDB will be running.
Step 2: Crafting the Docker Compose File
Create a directory named ferretdb-stack and define a docker-compose.yml file. This file will orchestrate both the PostgreSQL backend and the FerretDB proxy service.
version: '3.8'
services:
postgres:
image: postgres:16-alpine
container_name: ferretdb_backend
environment:
POSTGRES_USER: ferret_user
POSTGRES_PASSWORD: SecurePassword123
POSTGRES_DB: ferret_db
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ferret_user -d ferret_db"]
interval: 10s
timeout: 5s
retries: 5
ferretdb:
image: ghcr.io/ferretdb/ferretdb:latest
container_name: ferretdb_proxy
restart: always
ports:
- "27017:27017"
environment:
- FERRETDB_POSTGRESQL_URL=postgres://ferret_user:SecurePassword123@postgres:5432/ferret_db
depends_on:
postgres:
condition: service_healthy
volumes:
pgdata:Step 3: Launching the Services
Navigate to your directory and initialize the stack using the Docker CLI:
docker compose up -dVerify that both containers are running optimally by inspecting the logs:
docker compose logs -f ferretdbYou should see log lines indicating that FerretDB has successfully connected to the PostgreSQL backend and is now listening for incoming MongoDB wire protocol connections on port 27017.
Verifying the Connection
To confirm that the proxy layer functions correctly, use the standard MongoDB shell utility (mongosh) to interact with your new open-source backend.
mongosh "mongodb://127.0.0.1:27017/ferret_db"Once connected, run standard administrative and CRUD operations to test compatibility:
// Insert a document into a collection
db.customers.insertOne({ name: "Acme Corp", industry: "SaaS", active: true });
// Query the document
db.customers.find({ industry: "SaaS" });If you log into the PostgreSQL instance directly via psql, you will notice that FerretDB has automatically created schemas and tables corresponding to your MongoDB databases and collections, storing the document data efficiently within PostgreSQL columns.
Production Considerations & Performance Optimization
While the initial setup is straightforward, running FerretDB and PostgreSQL at enterprise scale requires deliberate optimization strategies. Keep the following operational parameters in mind:
1. Indexing Strategy
MongoDB relies on explicit index definitions via createIndex(). FerretDB translates these commands into native PostgreSQL indexes on jsonb fields. Ensure your application explicitly defines indexes for frequently queried fields to prevent PostgreSQL from resorting to costly sequential table scans.
2. Connection Pooling
MongoDB applications frequently open large connection pools. Because PostgreSQL utilizes a process-per-connection model, high connection counts can rapidly degrade performance. It is highly recommended to introduce a connection pooler like PgBouncer between FerretDB and PostgreSQL in high-traffic production environments.
3. Feature Compatibility
While FerretDB covers a significant portion of common MongoDB aggregation pipeline operators and CRUD mechanisms, it is an evolving project. Advanced, proprietary features unique to recent commercial versions of MongoDB (such as highly specific graph lookups or complex change streams) may have varying levels of support. Always execute rigorous integration testing with your specific application workload before finalizing production migration plans.
---Conclusion
The combination of FerretDB and PostgreSQL offers a powerful, production-ready path forward for organizations looking to break free from restrictive document database licenses. By utilizing PostgreSQL as a battle-tested storage layer and FerretDB as a transparent translation proxy, enterprises can confidently run their MongoDB-designed applications on a completely open-source foundation, lowering Total Cost of Ownership (TCO) while maintaining architectural flexibility.
