> ## Documentation Index
> Fetch the complete documentation index at: https://docs.thoras.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Persistent Storage

> Configure the persistent volume Thoras uses to retain historical usage metrics, and optionally point Thoras at an external TimescaleDB.

To produce production-grade predictions, Thoras needs durable storage for
historical usage metrics. The chart supports two independent pieces of state:

1. A Kubernetes
   [persistent volume](https://kubernetes.io/docs/concepts/storage/persistent-volumes/)
   (PV) attached to the metrics collector.
2. A TimescaleDB instance for time-series storage. The chart deploys one
   in-cluster by default; you can point it at an external database instead.

## Understanding Storage Requirements

You'll want to ensure Thoras has the disk space it needs now and in the future.
This may or may not require configuration based on your backend storage
provider.

### Understanding Usage

The storage requirement for a managed workload is `1GB`. So for a cluster with
twenty managed workloads, Thoras requires `20GB` of disk space.

### Understanding Kubernetes Storage Backend

In general there are two patterns for Kubernetes storage backends with regard to
disk space configuration:

#### Growable Storage Backends

These are PV storage backends that don't enforce a fixed size, they dynamically
grow as-needed and require no Thoras configuration to specify volume size.
Examples include:

* `AWS Elastic File System (EFS)`
* `Google Cloud Filestore (enterprise tier)`
* `Azure Files`
* `CephFS`

**Action:** If you use one of these backends, you don't need to allocate disk
space in the Thoras configuration, the disk will automatically grow to meet your
needs.

#### Fixed-Size Storage Backends

These are PV storage backends that require explicit provisioning of a fixed
capacity and enforce the size specified in the `PersistentVolumeClaim`. These
backends require you to specify the desired size of the disk, which you should
configure as a Helm chart value (read on for details on how to do that).
Examples include:

* `AWS Elastic Block Store (EBS)`
* `Google Persistent Disk (GCP PD)`
* `Azure Disk Storage`
* `VMware vSphere Volumes`

**Action:** If you use a fixed-size storage backend, you'll need to specify the
volume size as a Helm value:

1. Determine how much total size will be needed using
   [guidance above](#understanding-usage)
2. Configure the storage size by setting the following helm value:

```yaml theme={null}
metricsCollector:
  persistence:
    # Or whatever size needed based on your math from step #1
    pvcStorageRequestSize: "100Gi"
```

## Managing Persistent Volumes

You may have an established workflow for provisioning Kubernetes Persistent
Volumes (PV). That's great! Here's how to get up and running depending on your
preferred approach:

### Referencing an existing `StorageClass` provisioner

If you have a Kubernetes `StorageClass` that you'd like to use to dynamically
provision your PV (such as an
[EFS StorageClass](https://github.com/kubernetes-sigs/aws-efs-csi-driver/blob/master/examples/kubernetes/dynamic_provisioning/specs/storageclass.yaml)).
In that case, simply reference the storage class name in your Thoras helm chart
`values.yaml`:

```yaml theme={null}
metricsCollector:
  persistence:
    storageClassName: "{{ YOUR_STORAGE_CLASS_NAME }}"
```

<Note>
  `metricsCollector.persistence.enabled` defaults to `null`, which auto-enables
  persistence as soon as you set any of `storageClassName`,
  `pvcStorageRequestSize`, or `createEFSStorageClass.fileSystemId`. Setting
  `enabled: true` is only necessary if you want to force persistence on without
  configuring any of the above.
</Note>

### Referencing an existing PV

If you have a workflow for provisioning a PV and would like to simply reference
the PV directly by name, add the following config block to your Helm
`values.yaml`:

```yaml theme={null}
metricsCollector:
  persistence:
    enabled: true
    volumeName: "{{ YOUR_VOLUME_NAME_HERE }}"
```

## External TimescaleDB (BYODB)

The chart deploys an in-cluster TimescaleDB by default. If you'd rather manage
TimescaleDB yourself, for backups, HA, or shared infrastructure, point Thoras at
an external database instead:

```yaml theme={null}
externalTimescale:
  # Full postgres DSN, including the database name.
  dsn: "postgres://user:password@host:5432/tsdb?sslmode=require"
```

Or reference an existing Secret containing the DSN:

```yaml theme={null}
externalTimescale:
  secretRefName: my-timescale-dsn
  secretRefKey: dsn
```

When either is set, the chart skips deploying its bundled TimescaleDB and wires
all components to the external database. The TimescaleDB extension must be
pre-installed on the external database.

See [Credentials](/installation/credentials) for how the DSN interacts with the
other credentials Thoras manages.

## Questions?

For help, email [support@thoras.ai](mailto:support@thoras.ai).
