What Database Does Invidious Use? PostgreSQL Configuration and Setup

Invidious uses PostgreSQL as its primary database, configured via a postgres:// URI in the database_url configuration field, while SQLite is reserved solely for temporary NewPipe import operations.

The open-source Invidious project (iv-org/invidious) stores all persistent application data—including user accounts, video metadata, playlists, and sessions—in PostgreSQL. The Crystal-based codebase establishes a single global connection at startup and relies on PostgreSQL-specific features for all CRUD operations.

How Invidious Connects to PostgreSQL

Database Configuration Setup

Invidious expects database credentials through the database_url property defined in src/invidious/config.cr. The configuration class declares this as a URI type that parses standard PostgreSQL connection strings:

property database_url : URI = URI.parse("")

See src/invidious/config.cr lines 9-11.

The example configuration file demonstrates the expected format:

#database_url: postgres://kemal:kemal@localhost:5432/invidious

Reference: config/config.example.yml lines 39-40.

Alternatively, you can define individual connection parameters under a db key in your config.yml, which the Config.load method combines into the final URI internally.

Connection Initialization

During application startup, Invidious opens the database connection using the crystal-db library interface. The global constant PG_DB is initialized in the main entry point:

PG_DB = DB.open CONFIG.database_url

See src/invidious.cr lines 63-65.

If this connection attempt fails, the application prints an error message and exits immediately (lines 66-68 of the same file). This design ensures the server cannot run without database connectivity.

PostgreSQL Operations and Query Patterns

All database interactions throughout Invidious use the PG_DB handle exclusively. The application follows a consistent pattern for data access:

  • Writes: PG_DB.exec for INSERT, UPDATE, DELETE
  • Reads: PG_DB.query_one?, PG_DB.query_all, or PG_DB.scalar for SELECT statements

For example, user lookups in src/invidious/database/users.cr follow this signature:

def find_by_email(email : String) : User?
  PG_DB.query_one?("SELECT * FROM users WHERE email = $1", email, as: User)
end

The src/invidious/database/ directory contains modules for users, videos, playlists, and sessions, all implementing PostgreSQL-specific SQL dialects and migration schemas. This architecture provides type-safe database access while maintaining PostgreSQL as the single source of truth.

SQLite Usage in Invidious (Limited Scope)

While PostgreSQL handles all production data, Invidious does utilize SQLite for one specific edge case: importing NewPipe subscription exports. When a user uploads a NewPipe database file for migration, the code creates a temporary SQLite connection to read the foreign schema:

DB.open("sqlite3://" + tempfile.path) do |db|
  # Parse export and migrate data into PostgreSQL

end

See src/invidious/user/imports.cr lines 306-307.

This SQLite database exists only for the duration of the import operation and is destroyed immediately after the data transfers to PostgreSQL. It is never used for caching, session storage, or any other runtime functionality.

Configuration Examples for Production

To configure your Invidious instance with PostgreSQL, use either the unified URL format or individual parameters:

Option 1: Database URL (Recommended)

database_url: postgres://myuser:[email protected]:5432/invidious

Option 2: Individual Components

db:
  user: myuser
  password: mypassword
  host: db.example.com
  port: 5432
  dbname: invidious

Both methods result in the CONFIG.database_url value passed to DB.open during initialization.

Summary

  • Invidious requires PostgreSQL for all persistent storage, including users, videos, playlists, and sessions.
  • The connection initializes at startup via PG_DB = DB.open CONFIG.database_url in src/invidious.cr.
  • Configuration accepts standard postgres:// URIs defined in src/invidious/config.cr and config/config.example.yml.
  • All database modules in src/invidious/database/ use PostgreSQL-specific queries and the PG_DB global handle.
  • SQLite appears only in src/invidious/user/imports.cr for temporary NewPipe data migration and cannot serve as a primary database.

Frequently Asked Questions

Does Invidious support MySQL or MariaDB?

No. According to the source code in src/invidious/config.cr and src/invidious.cr, Invidious exclusively supports PostgreSQL connection URIs. The codebase uses PostgreSQL-specific SQL dialects and parameterized queries ($1, $2 syntax) that are not compatible with MySQL. Attempting to use a mysql:// URI will cause the application to fail at startup.

Can I use SQLite as the primary database for Invidious?

No. While the codebase contains SQLite drivers for the NewPipe import feature in src/invidious/user/imports.cr, there is no configuration path to use SQLite for the main application data. The PG_DB constant and all database modules assume a PostgreSQL backend, and the migration system relies on PostgreSQL-specific data types and constraints.

How do I configure the database connection URL?

Set the database_url field in your config.yml to a valid PostgreSQL URI format: postgres://username:password@host:port/database. This value is parsed by the URI class in src/invidious/config.cr and passed to DB.open during initialization. If you prefer not to expose credentials in a URL string, define the individual db sub-keys (user, password, host, port, dbname) instead, which Invidious combines internally into the required URI format.

What happens if the PostgreSQL connection fails on startup?

If DB.open CONFIG.database_url raises an exception in src/invidious.cr (lines 63-68), the application catches the error, prints a failure message to stderr, and exits with a non-zero status code. Invidious does not implement fallback databases or graceful degradation without PostgreSQL, ensuring data consistency by refusing to start until the database is accessible.

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 →