Database Requirements for Plane: PostgreSQL Configuration Guide

Plane requires a PostgreSQL database (version 9.6 or higher) and configures connections exclusively through environment variables, supporting either a DATABASE_URL connection string or individual POSTGRES_* variables.

Plane's Django-based backend relies on PostgreSQL as its primary data store. Understanding the database requirements for Plane is essential for production deployments and local development setups. The configuration system, defined in apps/api/plane/settings/common.py, parses your environment to establish database connections using either dj-database-url or discrete configuration variables.

Core Database Requirements

Plane’s backend is built on Django and requires PostgreSQL as the sole supported database engine. The minimum supported version is 9.6, though any version compatible with Django’s django.db.backends.postgresql backend will work.

The fundamental requirements are:

  • PostgreSQL instance accessible from your Plane containers or processes
  • Network connectivity between the application host and database host/port
  • Environment variables configured in your shell or .env file
  • (Optional) Read replica configuration for scaling read operations

Configuration Methods

Plane supports two distinct methods for supplying database credentials. You can use either the consolidated DATABASE_URL format or individual environment variables, but never both simultaneously for the primary connection.

Using DATABASE_URL

If you provide a DATABASE_URL environment variable, Plane delegates parsing to the dj-database-url library. This approach is ideal for Platform-as-a-Service (PaaS) environments like Heroku or Railway.

In apps/api/plane/settings/common.py, the logic appears as:

if os.getenv("DATABASE_URL"):
    DATABASES = {"default": dj_database_url.config()}

The URL format follows the standard PostgreSQL connection string:

DATABASE_URL=postgres://user:password@host:port/dbname

Using Individual Environment Variables

If DATABASE_URL is absent, Plane falls back to discrete variables defined in apps/api/plane/settings/common.py (lines 190-199). You must provide all of the following:

Variable Description Default
POSTGRES_DB Database name —
POSTGRES_USER Database user —
POSTGRES_PASSWORD User password —
POSTGRES_HOST Database host address —
POSTGRES_PORT Port number 5432

The Django settings dictionary is constructed as:

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": os.getenv("POSTGRES_DB"),
        "USER": os.getenv("POSTGRES_USER"),
        "PASSWORD": os.getenv("POSTGRES_PASSWORD"),
        "HOST": os.getenv("POSTGRES_HOST"),
        "PORT": os.getenv("POSTGRES_PORT", "5432"),
    }
}

Read Replica Configuration (Optional)

For high-availability deployments, Plane supports a single read replica through the ENABLE_READ_REPLICA flag. When set to 1, the application configures a secondary connection named replica using the same pattern as the primary database.

In apps/api/plane/settings/common.py (lines 202-215), the replica configuration mirrors the primary logic:

  • If DATABASE_READ_REPLICA_URL exists, it is parsed via dj_database_url.parse()
  • Otherwise, individual POSTGRES_READ_REPLICA_* variables are used

Required variables when using discrete configuration:

  • POSTGRES_READ_REPLICA_DB
  • POSTGRES_READ_REPLICA_USER
  • POSTGRES_READ_REPLICA_PASSWORD
  • POSTGRES_READ_REPLICA_HOST
  • POSTGRES_READ_REPLICA_PORT (optional, defaults to 5432)

Minimal Configuration Example

Below is a complete .env configuration showing both primary and optional read replica setups. This mirrors the official .env.example file in the repository:


# Primary PostgreSQL connection - required

POSTGRES_DB=plane
POSTGRES_USER=plane_user
POSTGRES_PASSWORD=super_secret_password
POSTGRES_HOST=localhost
POSTGRES_PORT=5432

# Alternative: Single URL form (uncomment to use instead of above)

# DATABASE_URL=postgres://plane_user:super_secret_password@localhost:5432/plane

# Read replica configuration - optional

ENABLE_READ_REPLICA=1
POSTGRES_READ_REPLICA_DB=plane_replica
POSTGRES_READ_REPLICA_USER=plane_replica_user
POSTGRES_READ_REPLICA_PASSWORD=replica_secret
POSTGRES_READ_REPLICA_HOST=replica-host.example.com
POSTGRES_READ_REPLICA_PORT=5432

# Or use: DATABASE_READ_REPLICA_URL=postgres://...

Summary

  • Plane requires PostgreSQL (version 9.6+) as its only supported database engine
  • Configure via environment variables using either DATABASE_URL or individual POSTGRES_* settings in apps/api/plane/settings/common.py
  • Read replicas are optional and activated by setting ENABLE_READ_REPLICA=1 with corresponding replica variables
  • dj-database-url handles URL parsing when using connection string formats
  • Default port is 5432 when not explicitly specified in environment variables

Frequently Asked Questions

Does Plane support MySQL or SQLite?

No. According to the source code in apps/api/plane/settings/common.py, Plane exclusively uses Django’s django.db.backends.postgresql engine. The configuration logic is hardcoded for PostgreSQL, and no other database backends are supported.

What PostgreSQL version is required for Plane?

Plane requires PostgreSQL 9.6 or higher. Any version compatible with Django’s PostgreSQL backend will work, but for production deployments, using PostgreSQL 12+ is recommended for better performance and long-term support.

Can I use a managed PostgreSQL service like Amazon RDS?

Yes. Since Plane configures the database entirely through environment variables, any PostgreSQL-compatible service works, including Amazon RDS, Google Cloud SQL, Azure Database for PostgreSQL, or Supabase. Simply provide the connection details via DATABASE_URL or the discrete POSTGRES_* variables.

How do I debug database connection issues in Plane?

Verify that the DATABASE_URL or individual POSTGRES_* variables are loaded in your environment. You can test the Django database configuration by running python manage.py check --database default from the apps/api directory. If using read replicas, ensure ENABLE_READ_REPLICA is exactly 1 and that replica variables are properly prefixed with POSTGRES_READ_REPLICA_.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →