Self-hosting overview
Backstory ships as one Helm chart, plus a single-virtual-machine install for a pilot. Recordings, exports, and attachments sit in an object store. The app servers do not hold them.
| Install | You provide | Recordings live on | Minimum |
|---|---|---|---|
external | Postgres 16 with pgvector, ClickHouse 24.8+, and a store. Valkey and LiveKit if you want Live Assist | The bucket you bring. The Backstory nodes stay small | 2 nodes × 4 vCPU / 8 GB for the Backstory pods |
bundled | A Kubernetes cluster with a default StorageClass | MinIO, on its own volume, separate from Postgres and ClickHouse | 1 node × 8 vCPU / 32 GB, 500 GB SSD. 16 GB is the hard floor |
single VM | One machine with Docker | MinIO on that machine’s disk | 8 vCPU / 32 GB / 500 GB. 16 GB is the hard floor |
An air-gapped install is whichever of those it sits on, with images from your own registry. The chart also has a saas profile, which is Backstory’s own cloud. Capacity past these floors is on Sizing and retention.
Where you set the store
Section titled “Where you set the store”The chart or the virtual-machine env file only carries a starting store. After install, the instance owner opens Storage setup in the account menu and chooses Amazon Web Services, Google Cloud, Microsoft Azure, or the store on this install (MinIO, Ceph, or the bundled disk). Saving there replaces the starting store. The API, gateway, and worker pick it up within a minute.
Google Cloud uses the access key and secret from Cloud Storage, under Interoperability. Azure uses the storage account, account key, and container. On Amazon, a role on the machine can sign for recordings and exports. Recorded call audio still needs a key, because that upload runs in a separate process.
Cluster backups stay in the chart (bundled.backups, bucket backstory-backups). That screen does not change them.
Install (bundled)
Section titled “Install (bundled)”helm dependency update deploy/helm/backstoryhelm upgrade --install backstory deploy/helm/backstory -n backstory --create-namespace \ -f deploy/helm/backstory/values-bundled.yaml --set bundled.acknowledgeSizing=true# once the operators are running:helm upgrade backstory deploy/helm/backstory -n backstory \ -f deploy/helm/backstory/values-bundled.yaml --set bundled.acknowledgeSizing=true --set bundled.createClusters=trueInstall (external)
Section titled “Install (external)”Set datastores.postgres.urlSecret, datastores.clickhouse.addr, and datastores.s3.* in your values file and install with profile: external. Those S3 settings are the starting store. Amazon, Google Cloud, Azure, MinIO, Ceph, and NetApp StorageGRID are chosen afterward in Storage setup.
Install (single virtual machine)
Section titled “Install (single virtual machine)”From deploy/selfhosted:
cp .env.selfhosted.example .env# edit .env: domain, master key, and the generated passwordsdocker compose -f docker-compose.selfhosted.yml --env-file .env up -dThis is one machine, with no extra replicas. Use the Helm chart for anything past a pilot.
Memory safety
Section titled “Memory safety”Every Backstory pod runs with requests equal to limits and GOMEMLIMIT at 85% of the limit. The gateway holds at most one chunk per connection; backlog stays in browsers. Datastores must never share a memory limit with application pods.
Upgrades
Section titled “Upgrades”helm upgrade with the new chart version. Database migrations are expand-and-contract and run automatically on worker start; rollbacks are safe within one minor version.
Retention
Section titled “Retention”Per-project retention is in days for replays, events, and aggregates. On Amazon and on a store on this install, expiry is a lifecycle rule keyed on the retention-class object tag, plus a daily cleanup. On Google Cloud and Azure, the daily cleanup deletes expired objects.