Using PostgreSQL for the Database
Athena keeps all of its state — agents, collections, deployments, commands, compliance data, users, scheduled jobs, and the audit trail — in a single database. Out of the box it uses an embedded SQLite database, which needs no separate server and is ideal for most installations. For larger fleets or where you want the database to live on a managed, backed-up database server, Athena can instead run on PostgreSQL. This page explains when to switch, how to point Athena at a PostgreSQL server, and how to confirm it worked.
Athena ships two database providers: SQLite (the default) and
PostgreSQL. There is no SQL Server provider. Both are selected at startup
through the Database configuration section — see
Configuration.
SQLite or PostgreSQL?#
Both providers run the exact same Athena. The choice is operational, not about features:
| SQLite (default) | PostgreSQL | |
|---|---|---|
| Where the data lives | A single file on the Athena server (athena.db). | On a PostgreSQL server you run and manage separately. |
| Extra services to run | None — it is embedded in the server. | A reachable PostgreSQL instance. |
| Backups | Copy the database file; Athena's built-in backup does this for you. | Use your PostgreSQL server's own backup tooling. Athena's in-console Optimize and file-copy backup apply to SQLite. |
| Good fit for | Single-server installs and most fleets. | Sites that standardise on a central, HA, or externally backed-up database tier. |
If you are unsure, start with SQLite. It is the default, requires no setup, and its backups are self-contained. You can move to PostgreSQL later with a fresh installation.
Preparing the PostgreSQL server#
Athena creates and upgrades its own tables on start-up (see Schema creation), so you do not need to load a schema by hand. You only need to provide an empty database and an account that owns it. On your PostgreSQL server, create a login role and a database and grant the role ownership — for example:
CREATE ROLE athena LOGIN PASSWORD 'a-strong-password';
CREATE DATABASE athena OWNER athena;
Make sure the Athena server can reach the PostgreSQL host and port (default 5432)
over the network, and that PostgreSQL is configured to accept connections from the Athena
server's address. Because Athena is designed for
air-gapped operation, the PostgreSQL server should live inside the
same isolated network as Athena — no internet access is required by either side.
Pointing Athena at PostgreSQL#
Set two keys in the Database section: Provider to
PostgreSQL, and ConnectionString to a standard PostgreSQL connection
string. In appsettings.json that looks like:
{
"Database": {
"Provider": "PostgreSQL",
"ConnectionString": "Host=db.internal;Port=5432;Database=athena;Username=athena;Password=a-strong-password"
}
}
The provider name must be exactly PostgreSQL (the default is Sqlite).
The connection string uses the usual PostgreSQL keywords — the ones you will most often set are:
| Keyword | Purpose |
|---|---|
Host | PostgreSQL server hostname or IP. |
Port | Server port (default 5432). |
Database | The database name you created for Athena. |
Username | The login role Athena connects as. |
Password | That role's password. |
The database provider and connection string are read once at start-up, so a change here takes effect after the server restarts. In the console, Settings → Database shows the active provider as read-only for exactly this reason — you switch providers by editing configuration and restarting, not from the UI. See Database Backup & Maintenance for that screen.
Setting it with environment variables#
Every configuration key can also be supplied as an environment variable, which is the cleaner
choice for a container deployment and keeps the password out of appsettings.json.
Nested keys join the section and key names with a double underscore:
Database__Provider=PostgreSQL
Database__ConnectionString=Host=db.internal;Port=5432;Database=athena;Username=athena;Password=a-strong-password
Environment variables take precedence over appsettings.json. For the full
precedence order and the double-underscore convention, see
Configuration.
The connection string contains the database password. Provide it as an environment variable or a protected configuration file, restrict who can read it, and rotate the PostgreSQL password if it may have been exposed.
Automatic schema creation#
When Athena starts against a PostgreSQL database, it connects, creates any tables it does not find, and applies any pending schema upgrades automatically. Point it at an empty database and it will build everything it needs on first run; on later upgrades it migrates the existing schema forward in place. You do not run migration scripts yourself.
Athena's built-in scheduler also stores its jobs in the same
database, so scheduled deployments, commands, and maintenance jobs persist across restarts on
PostgreSQL just as they do on SQLite. Those scheduler tables use a qrtz_ name
prefix; leave them alone.
Verifying the connection#
After restarting, confirm Athena is using PostgreSQL in either of these ways:
- In the console, open Settings → Database. The Database Information
section shows the active Provider — it should read
PostgreSQL. - Query the server health endpoint. The database component reports the provider it initialised with, so a healthy response from a PostgreSQL install names that provider.
If the server starts cleanly and the dashboard loads with your existing agents (or an empty fleet on a brand-new database), the connection is working.
Optional performance keys#
Two additional keys in the Database section apply to any provider and rarely need
changing:
| Key | Default | Notes |
|---|---|---|
HeartbeatBatchDelayMs | 3000 | Batching window, in milliseconds, for writing agent heartbeats. A larger window trades freshness for fewer, larger writes on a busy fleet. |
SlowQueryThresholdMs | 500 | Queries that take longer than this (in milliseconds) are flagged in the server log, which is handy for spotting a slow or distant database. |
Troubleshooting#
| Symptom | Likely cause & fix |
|---|---|
| Server won't start; log mentions the provider was not found. | The Provider value must be exactly PostgreSQL (or Sqlite). Check for typos or a stray value. |
| Startup fails connecting to the database. | Verify the Host, Port, Database, Username, and Password in the connection string, that the PostgreSQL server is reachable from the Athena host, and that PostgreSQL accepts connections from that address. |
| Console still shows SQLite after editing config. | The provider is bound at start-up — restart the Athena server so the new setting is read. |
| Slow queries flagged in the log. | Confirm low latency between Athena and the database, and that the PostgreSQL server is adequately resourced. Adjust SlowQueryThresholdMs only to change the reporting threshold. |
Related#
- Configuration — the full
Databasesection, configuration precedence, and the environment-variable convention. - Database Backup & Maintenance — the Settings → Database screen, backups, and optimization.
- Installation — first-run setup and persistent volumes.
- Server Health & Monitoring — the database health component that reports the active provider.
- Air-Gapped Operation — keeping the database inside the isolated network.