---
title: "Persistence"
description: "Reference for the persistence.conf configuration file."
stack: "Community Stack (open source) — version 0.21.0"
stack_version: "0.21.0"
stack_comparison: https://docs.walt.id/community-vs-enterprise.md
canonical_url: https://docs.walt.id/community-stack/issuer2/configurations/config-files/persistence
generated: 2026-07-20
---
# Persistence Configuration

The `persistence.conf` file chooses where the issuer keeps short-lived OpenID4VCI state (issuance sessions, codes, tokens). The default is in-memory storage; switch to Redis when you run more than one issuer instance and they need to share that state.

## File Location

```
waltid-services/waltid-issuer-api2/config/persistence.conf
```

## When This Is Used

`persistence.conf` is only read when the `persistence` feature is enabled in `_features.conf`:

```hocon
# _features.conf
enabledFeatures = ["persistence"]
```

Without the feature, the issuer always uses in-memory storage, so all state is lost on restart and cannot be shared across instances.

## Configuration Options

| Property | Type | Required | Default | Description |
|----------|------|----------|---------|-------------|
| `type` | String | No | `"memory"` | `memory`, `redis`, or `redis-cluster`. |
| `nodes` | Array&lt;{host, port}&gt; | For Redis | – | Redis nodes. `redis` requires **exactly one** node; `redis-cluster` takes one or more. |
| `user` | String | No | – | Redis username (Redis ACL / AUTH). |
| `password` | String | No | – | Redis password. |

A `redis` type with zero or multiple nodes fails at startup ("Redis persistence requires defining at least 1 node!" / "exactly 1 node is required").

**Error:**

Don't commit `password` to version control — supply it via an environment variable or secret manager.

## What Is Stored

When persistence is enabled, these stores move from memory into Redis:

| Store | Holds | Fallback TTL |
|-------|-------|--------------|
| Issuance sessions | Credential offer state and subject data | 5 min |
| Authorization codes | Authorization-code-flow codes | 5 min |
| Pre-authorized codes | Pre-authorized-code-flow codes and tx codes | 5 min |
| Pushed authorization requests (PAR) | PAR request state | 90 s |
| Refresh tokens | OpenID4VCI refresh tokens | 1 day |

Each entry is actually stored with a TTL until its own `expiresAt`; the values above are only the fallback used when no explicit expiry is set. Access tokens are self-contained and are **not** stored here.

## Example Configurations

```hocon
# persistence.conf — in-memory (default)
type = "memory"
```

```hocon
# persistence.conf — single Redis
type = "redis"
nodes = [{ host = "redis", port = 6379 }]
# user = "issuer-service"
# password = "secret-from-secrets-manager"
```

```hocon
# persistence.conf — Redis cluster
type = "redis-cluster"
nodes = [
    { host = "redis-node-1", port = 6379 },
    { host = "redis-node-2", port = 6379 },
    { host = "redis-node-3", port = 6379 }
]
```

## Docker Compose

Connection details come from `nodes` in `persistence.conf` (mounted into the container), not from environment variables. Point `nodes` at the Redis service name:

```yaml
services:
  issuer-api2:
    image: waltid/issuer-api2:latest
    ports:
      - "7002:7002"
    volumes:
      - ./config:/waltid-issuer-api2/config
    depends_on:
      - redis

  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes
    volumes:
      - redis-data:/data

volumes:
  redis-data:
```

## Related Configuration

- [Features](https://docs.walt.id/community-stack/issuer2/configurations/config-files/features.md) – Enable the persistence feature
- [Web](https://docs.walt.id/community-stack/issuer2/configurations/config-files/web.md) – Web server configuration
