Skip to main content
Bifrost persists two types of data - config (providers, virtual keys, governance rules) and logs (request/response records). Each has its own store, both defaulting to the top-level storage.mode.
ClickHouse is a logs-store-only backend. The config store supports only sqlite and postgres. To use ClickHouse for logs, set storage.logsStore.type: clickhouse and keep the config store on SQLite or PostgreSQL — see ClickHouse Logs Store below.
When any store uses SQLite the chart deploys a StatefulSet with a PVC. With PostgreSQL only (no SQLite) it deploys a Deployment. Mixing backends (e.g. config=postgres, logs=sqlite) still requires a StatefulSet.

SQLite (Default)

Simplest setup - no external database required. Bifrost runs as a StatefulSet with a persistent volume for the SQLite files.
Reuse an existing PVC (e.g. after a StatefulSet migration):
Upgrading from SQLite to PostgreSQL requires a data migration - the two stores are not compatible. Plan accordingly before switching storage.mode on a running deployment.

StatefulSet Migration (chart v2.0.0+)

Prior to v2.0.0, SQLite used a Deployment + manual PVC. v2.0.0 moved SQLite to a StatefulSet. If upgrading from an older chart:

Embedded PostgreSQL

The chart can deploy a PostgreSQL instance alongside Bifrost. Good for simple production setups where you don’t have an existing database.
Ensure the database is created with UTF8 encoding. The embedded PostgreSQL deployment handles this automatically. See PostgreSQL UTF8 Requirement for manual setups.
Using an existing secret (Vault, ESO, Sealed Secrets) If you manage secrets externally, set existingSecret instead of providing a plaintext password. The chart will not create its own secret — both the postgres pod (POSTGRES_PASSWORD) and the Bifrost pod (BIFROST_POSTGRES_PASSWORD) mount the password directly from your secret.
Verify the connection from Bifrost:

External PostgreSQL

Point Bifrost at an existing PostgreSQL instance - RDS, Cloud SQL, Azure Database, or self-managed.
For dynamic credentials such as AWS RDS IAM auth tokens, use passwordCommand instead of existingSecret:
Test connectivity before installing:

Separate PostgreSQL for Logs

By default the chart points both stores at the same PostgreSQL connection. Set storage.logsStore.postgres.enabled: true to give the logs store its own external PostgreSQL instance while the config store keeps using the top-level postgresql connection. Use this when config and logs have different scaling or cost profiles: a small highly-available database for configuration, and a separate instance sized for log write throughput so log traffic never competes with config reads.
This applies only when the logs store resolves to postgres. When storage.logsStore.postgres.enabled is false (the default), every logs-store connection setting falls back to the shared postgresql connection and behavior is unchanged. The whole postgres block is absent from the shipped values.yaml, so when you enable it, set each field you need explicitly. There are no per-field defaults apart from passwordKey.
For dynamic credentials on the logs database, use passwordCommand instead of existingSecret:

Mixed Backend (Config = Postgres, Logs = SQLite)

Run the config store on PostgreSQL (fast lookups, shared across replicas) while keeping logs on SQLite (simpler, cheaper for append-heavy workloads).
In mixed mode, Bifrost deploys a StatefulSet (because SQLite is in use) with both a PostgreSQL connection and a local PVC for the SQLite log store.
PostgreSQL connection pool tuning (high log volume):

ClickHouse Logs Store

ClickHouse is a column-oriented backend for the logs store, built for high-volume log ingestion and fast analytical queries at scale. Set storage.logsStore.type: clickhouse and provide a storage.logsStore.clickhouse block. The config store stays on SQLite or PostgreSQL.
ClickHouse applies to the logs store only. storage.configStore.type must remain sqlite or postgres. The chart does not deploy ClickHouse for you — point Bifrost at an existing ClickHouse instance (self-managed or ClickHouse Cloud).
With ClickHouse, the table TTL comes from logs_store.retention_days, which the chart does not expose yet. Set it in config.json directly if you need ClickHouse to expire rows on its own. Background log cleanup is controlled separately by bifrost.client.logRetentionDays. The PostgreSQL-only matviewRefreshInterval and matviewRefreshTimeout settings have no effect on ClickHouse.

Object Storage for Logs

Offload large request/response payloads from the database to S3 or GCS. The DB retains only lightweight index records; payloads are fetched on demand.

AWS S3

Required IAM permissions The IAM user or role needs the following permissions on your bucket:
storage.logsStore.objectStorageExcludeFields keeps selected LLM log payload fields in Postgres while still offloading the rest to object storage. Use DB payload field names such as output_message, input_history, raw_request, or raw_response. MCP logs always offload the full tool log and keep dashboard/table fields plus a 200-character input preview in Postgres. Using IAM role (IRSA / instance profile) instead of static keys:

Google Cloud Storage

MinIO (Self-Hosted)

Apply any of the object storage options above with:

Vector Store

A vector store is required for semantic caching. Choose from Weaviate, Redis, or Qdrant (embedded or external), or Pinecone (external only).

Weaviate

External Weaviate:

Redis / Valkey

External Redis / AWS MemoryDB:

Qdrant

External Qdrant:

Pinecone

Pinecone is external-only.
Apply any of the vector store options above with: