Topic · Data & state

PostgreSQL & databases for Django in production

Connecting, pooling, tuning, and troubleshooting the database behind Django: mostly PostgreSQL, with MySQL and SQLite.

connections are the scarce resourceDjangoworkers × threadsPoolpsycopg or PgBouncerPrimarywritesReplicaTimeouts, pooling, and backups matter more than tuning the server itself

PostgreSQL holds the data that matters, and its connections, locks, and queries decide how far a Django site can scale. Most performance problems end up here.

The guides cover connecting securely, pooling, timeouts, replicas, tuning, and the connection and authentication errors that appear in production.

24Set it up
32Run it well
3Check it
45Fix it

Set it up

Guides that take this from nothing to running in production.

  • How to Connect Django to PostgreSQL in Production

    Connecting Django to PostgreSQL in production is more than changing the DATABASES setting.

  • Connect Django to Managed PostgreSQL Securely

    Moving a Django app from a local database or self-managed PostgreSQL server to a managed PostgreSQL service sounds simple: update the host, username, and password, then deploy.

  • Set Up PgBouncer for Django

    Put PgBouncer between Django and PostgreSQL: transaction pooling, SCRAM auth, pool sizing, compatible Django settings, and monitoring.

  • Configure Django with MySQL in Production

    Run Django on MySQL or MariaDB in production: mysqlclient, utf8mb4, strict SQL mode, time zone tables, connection timeouts, TLS, and backups.

  • Deploy Multi-Tenant Django with django-tenants

    Deploy a schema-per-tenant Django SaaS with django-tenants: wildcard DNS and TLS, Nginx for subdomains, migrate_schemas in releases, tenant-aware caching, media, Celery, and pooling.

  • Run Django on SQLite in Production

    Run Django on SQLite in production safely: WAL mode, busy timeout and IMMEDIATE transactions, file placement and permissions, online backups, Litestream replication, and when to move on.

  • Deploy GeoDjango with PostGIS in Production

    Deploy a GeoDjango app: GDAL, GEOS, and PROJ libraries on servers and in Docker, enabling PostGIS on self-hosted and managed PostgreSQL, spatial indexes, backups, and upgrades.

  • Migrate a Django Project From SQLite to PostgreSQL

    Move a live Django project from SQLite to PostgreSQL without losing data: create the schema with migrate, transfer data with dumpdata and loaddata or pgloader, fix content types and sequences, and cut over with minimal downtime.

  • Run Elasticsearch or OpenSearch for Django in Production

    Run Elasticsearch or OpenSearch as the search backend for a Django app: choose managed or self-hosted, connect with django-opensearch-dsl or django-elasticsearch-dsl, index asynchronously with Celery, secure the cluster, and plan reindexing.

  • Deploy Django With the Official MongoDB Backend

    Use the official django-mongodb-backend in production: connect to MongoDB Atlas or a replica set, set ObjectId primary keys, handle migrations and contrib apps, configure indexes, transactions, and connection pooling, and know its current limitations.

  • Connect Django to Google Cloud SQL

    Connect Django to Cloud SQL for PostgreSQL securely: use the Cloud SQL Auth Proxy or Unix sockets on Cloud Run, private IP inside a VPC, IAM database authentication, connection limits, and running migrations against Cloud SQL.

  • Connect Django to Supabase Postgres

    Use Supabase as the PostgreSQL database for a Django app: choose the direct connection or the Supavisor pooler, handle transaction-mode pooling with server-side cursors off, require SSL, keep Row Level Security from blocking Django, and run migrations.

  • Connect Django to Neon Serverless Postgres

    Use Neon serverless PostgreSQL with Django: pooled versus direct connection strings, cold starts after scale-to-zero, transaction-mode pooling settings, branches for preview environments, and running migrations safely.

  • Run pgvector With Django in Production

    Store and search embeddings with pgvector in a production Django app: enable the extension with a migration, use VectorField, build HNSW indexes without blocking writes, tune memory, batch embedding generation in Celery, and plan for index size.

  • PostgreSQL vs MySQL for Django

    Compare PostgreSQL and MySQL (and MariaDB) as the database for a Django project: Django feature support, transactional DDL for migrations, JSON, full-text search, extensions, managed hosting, performance, and team experience.

  • Use Azure Database for PostgreSQL Flexible Server With Django

    Connect Django to Azure Database for PostgreSQL Flexible Server: choose public or private access, require TLS, use Microsoft Entra authentication with managed identity, enable built-in PgBouncer, allow extensions, and configure high availability and backups.

  • Run Django on Amazon Aurora PostgreSQL and Aurora Serverless v2

    Run Django on Amazon Aurora PostgreSQL: choose provisioned or Serverless v2 capacity, use writer and reader endpoints with a database router, add RDS Proxy for connection pooling and faster failover, set minimum ACUs, and plan upgrades and backups.

  • Run Django on CockroachDB

    Run Django on CockroachDB with the django-cockroachdb backend: match backend and Django versions, configure TLS connections, handle transaction retries, adjust migrations and primary keys, and understand what works differently from PostgreSQL.

  • Use Microsoft SQL Server With Django in Production

    Run Django on Microsoft SQL Server or Azure SQL with mssql-django: install the ODBC driver in Docker or Linux, configure the connection and encryption, handle collation and Unicode, migrations, and connection pooling, and know the backend’s limitations.

  • Back Up and Replicate a Django SQLite Database With Litestream

    Use Litestream to continuously replicate a Django SQLite database to S3-compatible storage: enable WAL mode, run Litestream as a sidecar or systemd service, restore on startup in containers, test point-in-time recovery, and know the limits of single-writer SQLite.

  • Add Meilisearch Search to a Django App in Production

    Run Meilisearch for Django search in production: deploy it with a master key and persistent storage, index models from signals or Celery, use scoped API keys for frontend search, configure filterable and sortable attributes, and rebuild indexes safely.

  • Use Typesense With Django for Fast Search

    Use Typesense with Django in production: run a Typesense node or cluster with an API key and persistent data, define collection schemas, sync models from Celery, use scoped search keys in the frontend, and rebuild collections with aliases for zero downtime.

  • Connect Django to Amazon RDS With IAM Authentication

    Connect Django to Amazon RDS PostgreSQL or Aurora with IAM database authentication instead of a static password: grant rds_iam, create an rds-db:connect policy, generate auth tokens in a custom database backend, and require TLS.

  • Run Procrastinate as a PostgreSQL Task Queue for Django

    Use Procrastinate, a PostgreSQL-based task queue, with Django in production: install the Django contrib app, define and defer tasks inside transactions, run workers with concurrency, schedule periodic tasks, use locks and queueing locks, and monitor jobs in the admin.

Run it well

Tuning, reliability, and operations once it works.

  • Configure Persistent Database Connections in Django

    Use CONN_MAX_AGE and CONN_HEALTH_CHECKS correctly: when persistent connections help, connection math, idle timeouts, ASGI caveats, and measuring gains.

  • Use Django's Built-In PostgreSQL Connection Pool

    Enable Django's native psycopg 3 connection pool: sizing per process, CONN_MAX_AGE rules, health checks, Gunicorn and ASGI behavior, and PgBouncer.

  • Route Django Reads to PostgreSQL Read Replicas

    Add PostgreSQL read replicas to Django: multi-database settings, routers, replication lag and read-your-writes, transactions, migrations, and tests.

  • Set PostgreSQL Statement Timeouts for Django

    Stop runaway queries from exhausting Django workers: set statement_timeout per connection or role, give migrations and Celery different limits, handle QueryCanceled errors, and work with PgBouncer.

  • Upgrade PostgreSQL to a New Major Version for Django

    Upgrade the PostgreSQL behind a Django app to a new major version: check Django and psycopg support, choose dump and restore, pg_upgrade, or logical replication, then analyze, verify, and roll back safely.

  • Tune PostgreSQL Autovacuum for Django

    Keep Django tables fast and small with autovacuum tuning: find dead tuples and bloat, set per-table thresholds for hot tables in migrations, raise cost limits, and remove blockers like long transactions.

  • Fast Pagination for Large Django Tables

    Paginate large Django tables without slow OFFSET and COUNT queries: keyset (cursor) pagination on an indexed column, DRF CursorPagination, avoiding exact counts, admin tips, and when page numbers are still fine.

  • Fast Bulk Inserts and Updates in Django

    Speed up large Django data loads and updates: bulk_create and bulk_update with batch_size, update() with F expressions, update_conflicts for upserts, transactions, disabling per-row signals, COPY for very large imports, and what bulk methods skip.

  • Tune PostgreSQL Settings for a Django Workload

    Tune PostgreSQL configuration for a Django app: shared_buffers, effective_cache_size, work_mem, max_connections with pooling, random_page_cost on SSDs, checkpoints and WAL, autovacuum, and statement timeouts, with safe starting values by server size.

  • Partition Large PostgreSQL Tables in a Django App

    Use PostgreSQL declarative partitioning for very large Django tables such as events, logs, and audit trails: range partitions by time, creating them with migrations or pg_partman, primary key constraints, ORM behaviour, and dropping old data instantly.

  • PostgreSQL Full-Text Search for Django in Production

    Run Django search on PostgreSQL full-text search in production: a stored SearchVectorField with a GIN index, weights and ranking, language configurations, trigram similarity for typos, keeping vectors updated, and when to move to a search engine.

  • Copy Production Data to Staging Safely (Anonymised)

    Give a Django staging environment realistic data without exposing customers: copy production, anonymise personal fields with a management command or tooling, subset large tables, disable outbound email and payments, and automate refreshes.

  • PostgreSQL High Availability and Failover for Django

    Keep a Django app running through database failures: managed Multi-AZ PostgreSQL, Patroni or CloudNativePG for self-hosted clusters, connection endpoints that follow the primary, CONN_HEALTH_CHECKS and retries, and testing failover.

  • Move a Django Database With Minimal Downtime Using Logical Replication

    Migrate a Django PostgreSQL database to a new server, provider, or major version with seconds of downtime: logical replication publications and subscriptions, schema copy, sequence sync, cutover steps, and verification.

  • A Practical Database Indexing Strategy for Django

    Decide which indexes a Django app needs: find slow queries, index foreign keys and filter and ordering columns, use composite, partial, covering, and expression indexes with Meta.indexes, remove unused indexes, and add them without locking production tables.

  • Use QuerySet.explain() and EXPLAIN ANALYZE to Speed Up Django Queries

    Read PostgreSQL query plans for Django ORM queries with QuerySet.explain(analyze=True, buffers=True): spot sequential scans, bad row estimates, sorts, and nested loops, run EXPLAIN safely on production, and turn plans into indexes and queryset fixes.

  • Index Django JSONField Queries With GIN on PostgreSQL

    Speed up Django JSONField lookups on PostgreSQL: choose GinIndex with jsonb_ops or jsonb_path_ops for containment queries, add expression B-tree indexes for specific keys, write queries that can use them, and build the indexes concurrently.

  • Remove PostgreSQL Table Bloat in Django With pg_repack

    Measure and remove PostgreSQL table and index bloat in a Django database without long locks: estimate bloat, understand why VACUUM FULL blocks the app, run pg_repack on large tables, reindex concurrently, and prevent bloat from returning.

  • Delete Old Rows in Django in Batches Without Hurting Production

    Implement data retention in Django: delete old logs, task results, sessions, and events in small batches with primary key ranges, avoid long locks and replica lag, handle cascades, schedule cleanup with Celery or cron, and consider partitioning for big tables.

  • Log Slow PostgreSQL Queries From Django With log_min_duration_statement

    Turn on PostgreSQL slow query logging for a Django app: set log_min_duration_statement, add auto_explain for plans, tag queries with application_name and SQL comments to find the view that sent them, and ship logs to your log platform without flooding it.

  • Manage PostgreSQL Connections for Django on Serverless Platforms

    Avoid connection exhaustion when Django runs on Lambda, Cloud Run, Vercel, or autoscaling containers: use pooled endpoints (RDS Proxy, Neon, Supabase pooler, PgBouncer), set CONN_MAX_AGE and server-side cursor options correctly, and cap concurrency per instance.

  • Backup and Restore PostgreSQL for Django Apps

    A Django app is only recoverable if its PostgreSQL data is recoverable. In production, that means more than occasionally running pg_dump.

  • Find and Fix N+1 Queries in Django

    Find and fix N+1 queries in Django: detect them in tests and logs, use select_related, prefetch_related, Prefetch objects, and annotations correctly.

  • Run Schema Changes on Large Tables in Django Safely

    Change large PostgreSQL tables from Django migrations without outages: lock_timeout, concurrent indexes, NOT VALID constraints, and batched backfills.

  • Find Slow Django Queries with pg_stat_statements

    Enable pg_stat_statements for a Django app, rank queries by total time, trace them back to ORM code, confirm plans with EXPLAIN ANALYZE, and fix them with indexes and better querysets.

  • PostgreSQL Point-in-Time Recovery for Django

    Set up point-in-time recovery for a Django PostgreSQL database with pgBackRest: WAL archiving, full and incremental backups, restoring to a timestamp before a bad migration, and managed-service PITR.

  • Add Database Indexes in Django Without Locking Tables

    Add PostgreSQL indexes to large tables in a live Django app without blocking writes: AddIndexConcurrently in non-atomic migrations, handling failed concurrent builds, finding missing indexes, and removing unused ones safely.

  • Deploy Django Across Multiple Regions

    Plan a multi-region Django deployment: decide between active-passive and active-active, route users with latency or geo DNS, place PostgreSQL primaries and read replicas, handle sessions, caches, Celery, and media per region, and test regional failover.

  • Use the Transactional Outbox Pattern With Django and Celery

    Stop losing or duplicating side effects when Django saves data and enqueues Celery tasks: compare transaction.on_commit with a transactional outbox table, write outbox rows atomically, relay them with a worker using SKIP LOCKED, and make consumers idempotent.

  • Run a Django Data Migration on a Large Table

    Backfill or transform millions of rows in Django without long locks or failed deploys: move heavy data changes out of schema migrations, batch updates by primary key, run them as resumable management commands or Celery jobs, and keep code compatible during the backfill.

  • Migrate a Django Integer Primary Key to BigInt Without Downtime

    Convert a Django AutoField primary key to BigAutoField before it overflows: estimate time to exhaustion, avoid the table-rewriting ALTER on big tables, add a new bigint column with triggers, backfill, swap keys and foreign keys, and handle sequences.

  • Rotate the Django Database Password Without Downtime

    Rotate PostgreSQL or MySQL credentials used by a Django app without outages: use two database roles or dual passwords, update secrets in the right order, restart web, Celery, and cron processes, handle PgBouncer, and automate rotation with Secrets Manager.

Check it

Review lists to run before launch or after a change.

  • PostgreSQL Production Checklist for Django

    Review PostgreSQL for a production Django app: roles and TLS, connections and pooling, memory settings, autovacuum, slow query visibility, backups, and upgrades.

  • Checklist for Moving a Django Database to Managed PostgreSQL

    Move a Django app’s self-hosted PostgreSQL to RDS, Cloud SQL, Azure, Neon, or another managed service: check versions and extensions, choose dump/restore or logical replication, handle roles and ownership, plan cutover and rollback, and verify Django afterwards.

  • Django Multi-Tenant SaaS Production Checklist

    A production checklist for multi-tenant Django SaaS apps: choose shared tables, schemas, or databases, enforce tenant isolation in queries and caches, scope files and background jobs, handle custom domains, run migrations per tenant, and test for cross-tenant leaks.

Fix it

Errors and symptoms, each traced to a cause and a fix.

Learning paths through this topic

Related topics