PayloadCMS Setup: PostgreSQL or FerretDB

PayloadCMSPostgreSQLFerretDBMongoDBDatabases

PayloadCMS supports three database backends: PostgreSQL, MongoDB (via its wire protocol), and SQLite. This post shows how to wire up the two production-ready options on Layerbase Cloud in under five minutes each, and makes the case for picking FerretDB instead of a managed MongoDB when you want the document model.

Contents

Which database should PayloadCMS use?

For most Payload projects, the answer is PostgreSQL. It handles relational data cleanly, the JSONB column type covers schema-flexible use cases when you need them, and the operational tooling around Postgres is unmatched (pg_dump, point-in-time recovery, every ORM and BI tool).

Pick FerretDB instead if:

  • Your data is genuinely document-shaped (deeply nested, schema-flexible, query-by-pattern)
  • Your team already knows MongoDB drivers and mongosh
  • You want the Mongo developer experience without the SSPL licensing risk

Pick SQLite only for local development or very small single-machine deployments. It is not what you want behind a production Payload install.

The rest of this post covers Postgres and FerretDB. Both are available on the Layerbase Cloud free tier with no credit card.

PayloadCMS with PostgreSQL

1. Create the database

Visit layerbase.com/create/postgresql, pick a name (e.g. payload-prod), and click Sign in and create. Provisioning takes about ten seconds. Copy the connection string from the dashboard; it looks like:

text
postgresql://layerbase:<password>@your-host.cloud.layerbase.dev:5432/app?sslmode=require

2. Install the Payload adapter

bash
pnpm add @payloadcms/db-postgres

3. Configure payload.config.ts

ts
import { buildConfig } from 'payload'
import { postgresAdapter } from '@payloadcms/db-postgres'

export default buildConfig({
  db: postgresAdapter({
    pool: {
      connectionString: process.env.DATABASE_URL,
    },
  }),
  collections: [
    /* your collections */
  ],
})

Put the connection string in .env:

text
DATABASE_URL=postgresql://layerbase:...@your-host.cloud.layerbase.dev:5432/app?sslmode=require

4. Run

bash
pnpm payload generate:types
pnpm dev

Payload runs migrations on first boot. Done.

PayloadCMS with FerretDB

FerretDB implements the MongoDB wire protocol on top of PostgreSQL. From Payload's perspective it is MongoDB, so you use the existing @payloadcms/db-mongodb adapter unchanged.

1. Create the database

Visit layerbase.com/create/ferretdb, name it, click Sign in and create. The dashboard will give you a Mongo-style connection string:

text
mongodb://layerbase:<password>@your-host.cloud.layerbase.dev:27017/app?tls=true

2. Install the Mongo adapter

bash
pnpm add @payloadcms/db-mongodb

The Mongo adapter, not a FerretDB-specific one. There is no FerretDB-specific adapter because the wire protocol is identical.

3. Configure payload.config.ts

ts
import { buildConfig } from 'payload'
import { mongooseAdapter } from '@payloadcms/db-mongodb'

export default buildConfig({
  db: mongooseAdapter({
    url: process.env.DATABASE_URL,
  }),
  collections: [
    /* your collections */
  ],
})

And .env:

text
DATABASE_URL=mongodb://layerbase:...@your-host.cloud.layerbase.dev:27017/app?tls=true

4. Run

bash
pnpm dev

That is the entire integration. Payload talks to FerretDB the same way it talks to MongoDB.

Why we recommend FerretDB over MongoDB

If you reach for "the document database," you are usually reaching for the developer experience: flexible schemas, expressive queries, the mongosh shell, the Node and Python drivers, the ecosystem. None of that requires MongoDB the product. FerretDB gives you all of it without the trade-offs that come with hosting real MongoDB.

Licensing: Apache 2.0 instead of SSPL

MongoDB ships under the Server Side Public License (SSPL), which restricts how managed providers can offer it. That is why every "MongoDB-compatible" managed service that is not MongoDB Atlas itself has had to either license MongoDB directly from MongoDB Inc. or run a fork. FerretDB is Apache 2.0. You can host it, embed it, redistribute it, fork it, ship it inside an on-prem product. No license review required.

Drop-in compatibility

Same wire protocol means the same drivers work:

  • mongoose, mongodb Node.js drivers
  • pymongo
  • mongo-go-driver
  • The Java, C#, Rust, and Ruby official drivers
  • mongosh for ad-hoc queries
  • Mongo Compass for browsing
  • The Payload @payloadcms/db-mongodb adapter

You do not change a single line of application code to switch from MongoDB to FerretDB.

Cheaper than MongoDB Atlas Serverless

MongoDB Atlas Serverless bills per read unit and per write unit, plus storage and egress. For workloads with variable read/write patterns the bill is hard to predict and often surprising. Layerbase Cloud charges a flat monthly fee per database plus optional add-ons (storage, always-on connections, larger plans), and the free tier covers small projects with no card. Predictable pricing matters more than the headline rate when you are running a real product.

Backed by Postgres under the hood

FerretDB stores your documents as JSONB inside a PostgreSQL table. Practical benefits:

  • ACID transactions handled by Postgres (not FerretDB-specific code)
  • Backups via pg_dump and managed snapshots, not Mongo-specific tooling
  • The full PostgreSQL extension ecosystem is available if you need it
  • One database engine to learn for ops if your stack already includes Postgres

For 90% of document workloads (CRUD, indexes, aggregations, transactions, change streams) this is invisible. For the other 10%, you get visibility into what is actually happening on disk.

When real MongoDB is the right call

A few Mongo-only features are not in FerretDB: Atlas Search, sharded clusters with chunk balancing, BSON-specific edge cases, and time-series collections as a first-class feature. If your app depends on any of those, host real MongoDB on Layerbase Desktop or SpinDB for development, and stick with MongoDB Atlas in production.

Local development with Layerbase Desktop

Cloud databases are great for staging and production. For local development, you want a database that runs on your machine without a network round-trip.

Layerbase Desktop ships PostgreSQL, FerretDB, MongoDB (yes, real MongoDB for local), and 17 other engines as one-click installs on macOS, Windows, and Linux. The dashboard, query console, and connection panel are the same as the cloud experience. Free for personal use.

For a CLI workflow, SpinDB is the open-source command-line version:

bash
npm i -g spindb
spindb create payload-dev --engine postgresql --start
spindb url payload-dev    # prints the connection string

Swap postgresql for ferretdb or mongodb for the document path. Point Payload's DATABASE_URL at the printed URL and you have a local development database in seconds.

Wrapping up

For a new Payload project, this is the shortest path to a production-ready database:

Both cloud options start on the free tier with no credit card. Both run the upstream binary directly. Both stay portable: the same connection string format works on every host, so you are never locked in.

Something not working?