# Configure Retention (/learn/events-store/how-to/configure-retention)



Events Store persists messages to disk. Without retention policies, storage grows indefinitely. KubeMQ provides three types of retention controls: **time-based**, **size-based**, and **count-based**. You can combine them — the most restrictive policy wins.

## Retention Options [#retention-options]

| Setting                | Config Key               | Default           | Description                                                    |
| ---------------------- | ------------------------ | ----------------- | -------------------------------------------------------------- |
| Max retention time     | `Store.MaxRetention`     | `1440` (24 hours) | Maximum age of messages in minutes. `0` = unlimited.           |
| Max channel size       | `Store.MaxQueueSize`     | `0` (unlimited)   | Maximum total bytes per channel. Oldest removed when exceeded. |
| Max message count      | `Store.MaxMessages`      | `0` (unlimited)   | Maximum messages per channel. Oldest removed when exceeded.    |
| Inactive channel purge | `Store.MaxPurgeInactive` | `1440` (24 hours) | Minutes of inactivity before an empty channel is purged.       |

## How Retention Works [#how-retention-works]

<Mermaid
  chart="graph TD
  E[(&#x22;Events accumulate<br/>in channel&#x22;)] --> C{&#x22;Check retention<br/>thresholds&#x22;}
  C -- &#x22;Age exceeded&#x22; --> P1[&#x22;Purge oldest by time&#x22;]
  C -- &#x22;Size exceeded&#x22; --> P2[&#x22;Purge oldest by size&#x22;]
  C -- &#x22;Count exceeded&#x22; --> P3[&#x22;Purge oldest by count&#x22;]
  C -- &#x22;All within limits&#x22; --> K[(&#x22;Keep all events&#x22;)]
  P1 --> R[(&#x22;Remaining events&#x22;)]
  P2 --> R
  P3 --> R

  class E,K,R data
  class P1,P2,P3 data"
/>

*As events accumulate, KubeMQ checks each retention threshold and purges the oldest events by time, size, or count — keeping everything that still fits within every limit.*

## Configure via Docker [#configure-via-docker]

Set retention options using environment variables:

<RunKubeMQ
  ports="[50000, 9090, 8080]"
  env="{
  STORE_MAX_RETENTION: '4320',
  STORE_MAX_QUEUE_SIZE: '1073741824',
  STORE_MAX_MESSAGES: '1000000',
  STORE_MAX_PURGE_INACTIVE: '10080',
}"
/>

This configures:

* **3-day retention** (4320 minutes)
* **1 GB max per channel** (1073741824 bytes)
* **1 million messages max per channel**
* **7-day inactive channel purge** (10080 minutes)

## Configure via Helm [#configure-via-helm]

Set retention in your `values.yaml`:

```yaml title="values.yaml"
store:
  maxRetention: 4320
  maxQueueSize: 1073741824
  maxMessages: 1000000
  maxPurgeInactive: 10080
```

Then install or upgrade:

```bash
helm upgrade kubemq kubemq/kubemq --values values.yaml
```

## Configure via Kubernetes Operator [#configure-via-kubernetes-operator]

Set retention in the KubeMQ CRD:

```yaml title="kubemq-cluster.yaml"
apiVersion: core.k8s.kubemq.io/v1beta1
kind: KubemqCluster
metadata:
  name: kubemq
spec:
  store:
    maxRetention: 4320
    maxQueueSize: 1073741824
    maxMessages: 1000000
    maxPurgeInactive: 10080
```

## Common Retention Strategies [#common-retention-strategies]

### Development (Short Retention) [#development-short-retention]

```bash
STORE_MAX_RETENTION=60          # 1 hour
STORE_MAX_MESSAGES=10000        # 10K messages
STORE_CLEAN_STORE=true          # Clean on restart
```

### Production — Event Streaming [#production--event-streaming]

```bash
STORE_MAX_RETENTION=10080       # 7 days
STORE_MAX_QUEUE_SIZE=5368709120 # 5 GB per channel
STORE_MAX_MESSAGES=0            # Unlimited messages
```

### Production — Event Sourcing [#production--event-sourcing]

```bash
STORE_MAX_RETENTION=0           # Unlimited (no time expiry)
STORE_MAX_QUEUE_SIZE=0          # Unlimited size
STORE_MAX_MESSAGES=0            # Unlimited messages
```

<Callout type="warn">
  Setting all retention values to `0` (unlimited) means events are stored indefinitely. Monitor disk usage with the [storage utilization thresholds](/learn/events-store/how-to/monitor-storage) to prevent disk exhaustion.
</Callout>

### Production — Compliance (Fixed Window) [#production--compliance-fixed-window]

```bash
STORE_MAX_RETENTION=525600      # 365 days (1 year)
STORE_MAX_QUEUE_SIZE=0          # Unlimited size
STORE_MAX_MESSAGES=0            # Unlimited messages
STORE_MAX_PURGE_INACTIVE=525600 # Purge inactive after 1 year
```

## Persistence and Recovery [#persistence-and-recovery]

### Clean Start [#clean-start]

To clear all stored data on startup:

<RunKubeMQ env="{ STORE_CLEAN_STORE: 'true' }" />

### Volume Persistence [#volume-persistence]

For data to survive container restarts, mount a volume to the store path:

<RunKubeMQ ports="[50000]" volume="kubemq-data:/kubemq/store" />

### Recovery from Corruption [#recovery-from-corruption]

If the server detects recovery errors on startup, it automatically removes and recreates the store directory. The `TruncateUnexpectedEOF` option (enabled by default) truncates corrupted file tails rather than failing.

<Callout type="info">
  File store tuning (`WriteBufferSize`, `ReadBufferSize`, `DiskSyncSeconds`, etc.) is rarely needed. The defaults are suitable for most workloads. See the [Events Store Reference](/learn/events-store/reference) for advanced settings.
</Callout>

## Related [#related]

* [Monitor Storage Utilization](/learn/events-store/how-to/monitor-storage) for disk usage thresholds
* [Resume After Disconnect](/learn/events-store/how-to/resume-after-disconnect) for durable subscription behavior
* [Events Store Reference](/learn/events-store/reference) for complete configuration
