Ghost CMS: MySQL by default, but SQLite still has a place

Ghost CMS: MySQL by default, but SQLite still has a place
Last reviewed: Aug 2025

Ghost’s v5.x series made MySQL 8 the officially supported database in production. The change gives the core team one stack to maintain and unlocks features that depend on MySQL-specific functions. Yet the single-file convenience of SQLite is still attractive for certain workloads, especially when you run Ghost inside Docker or on low-resource hardware. This guide explains when SQLite may be the better fit and how to switch without drama.


Why Ghost Uses MySQL Now

Reason Benefit you gain with MySQL
JSON columns and very large tables Native JSON type and higher size limits
Better concurrency Multiple writers without global locks
Future roadmap Upcoming analytics and reporting features rely on MySQL functions

Ghost ships just one “blessed” stack (Ubuntu + Node LTS + MySQL 8) to keep support overhead low.


Where SQLite Still Shines

Scenario Why SQLite helps
Single-author or low-traffic blogs Zero administration, no separate server process
Budget VPS or Raspberry Pi Far lower RAM and CPU usage than mysqld
Simple backups The whole site lives in one .db file
Air-gapped or USB deployments Database can sit on removable media
Docker deployments with SQLite The database file remains inside the container volume, so you spin up everything with a single docker compose up

Important note: SQLite allows many readers but only one writer at a time. Busy multi-author sites can hit write-lock contention.


Quick Pros and Cons

SQLite MySQL 8
Install footprint One 700 kB binary Full server (~500 MB) plus a running service
Backups Copy one file or use the hot-backup API mysqldump, replication or physical snapshots
Concurrency One writer (WAL mode helps) Many concurrent writers and readers
Ghost support Community best-effort Officially supported
Upgrading Ghost No database tweaks needed Must track MySQL major versions

Switching From MySQL to SQLite

Ghost does not officially QA SQLite in production. Use it only if you accept that trade-off.
  1. Export content from the running MySQL blog
    Admin area → Settings → Labs → Export content
    This downloads a ghost-export.json file to your computer.
  2. Start the new blog and import the JSON
    Admin area → Settings → Labs → Import content → select ghost-export.json

Check the post count

sqlite3 content/data/ghost.db "select count(*) from posts;"

If the number matches your old site, the migration is done.

Spin up a fresh Ghost instance that points to SQLite
Docker example (compose file excerpt)

services:
  ghost:
    image: ghost:5-alpine
    volumes:
      - ./content:/var/lib/ghost/content   # SQLite file lives here
    environment:
      database__client: sqlite3

On bare metal, add the following block to config.production.json before starting Ghost:

"database": {
  "client": "sqlite3",
  "connection": {
    "filename": "content/data/ghost.db"
  }
}

Moving Back to MySQL

  1. Spin up a MySQL 8 container (or package) and create an empty database/user.
  2. Edit config.production.json (or environment variables) to point Ghost at the new MySQL instance.
  3. Start Ghost, then import the same ghost-export.json through the Admin UI.

When SQLite Is Not the Right Choice

  • You expect heavy commenting or multi-author editing that generates many writes.
  • You need horizontal scaling across several web servers. SQLite over NFS is unreliable.
  • You rely on Ghost(Pro) hosting or the official Docker image configured for MySQL only.

Final Thoughts

For most production sites, staying on MySQL keeps you inside Ghost’s support envelope and prepares you for upcoming features. SQLite, however, remains a pragmatic option for side projects, self-hosted hobby blogs, lightweight Docker stacks, and resource-constrained devices. Because Ghost can import and export everything in a single JSON file, you can change engines in minutes and choose the best tool for each situation.

Happy blogging, whatever database you run!