> ## Documentation Index
> Fetch the complete documentation index at: https://hs-df36fa00.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Configure Persistence for Your Watt ServiceNet Node

> Choose between in-memory, JSON file, and PostgreSQL storage backends for your Watt ServiceNet node based on your durability and scalability needs.

Watt ServiceNet supports three storage backends. Choose based on your deployment requirements: in-memory for development, JSON file for simple persistent deployments, and PostgreSQL for production workloads that need full durability, encrypted secret storage, and multi-node support.

## Comparison

| Backend    | Use case                         | Durability                          | Requires                                                   |
| ---------- | -------------------------------- | ----------------------------------- | ---------------------------------------------------------- |
| In-memory  | Development, testing             | None — all state is lost on restart | Nothing                                                    |
| JSON file  | Small or single-node deployments | File system                         | `SERVICENET_REGISTRY_FILE`                                 |
| PostgreSQL | Production                       | Full ACID durability                | `SERVICENET_DATABASE_URL` + `SERVICENET_SECRET_BROKER_KEY` |

## In-Memory (Default)

When you start the node without any storage configuration, it defaults to in-memory storage. All registry state, providers, agents, and submissions exist only for the lifetime of the process.

```bash theme={null}
cargo run -p watt-servicenet-node
```

Or with Docker:

```bash theme={null}
docker run -p 8042:8042 watt-servicenet-node
```

<Note>
  In-memory mode is intentionally stateless. Use it for local development, integration tests, and CI pipelines where persistence is not needed.
</Note>

## JSON File Backend

Set `SERVICENET_REGISTRY_FILE` to a file path to enable file-backed persistence. The node creates the file and its parent directories automatically if they do not exist. State survives restarts.

```bash theme={null}
SERVICENET_REGISTRY_FILE=.data/registry.json cargo run -p watt-servicenet-node
```

The JSON file is read on startup and written after each state-changing operation. This backend is suitable for simple single-node deployments with low write volume. It is not suitable for high-concurrency workloads or deployments that need encrypted auth-context secret storage.

## PostgreSQL Backend

PostgreSQL is the recommended backend for production. It provides full ACID durability across all registry, receipt, health, trust, audit, and auth-context tables, and is required for encrypted secret broker storage.

<Steps>
  <Step title="Start a PostgreSQL instance">
    You can use any PostgreSQL 14+ server. For local development, the included Docker Compose file starts one for you.
  </Step>

  <Step title="Generate a secret broker key">
    The PostgreSQL backend requires a 32-byte base64-encoded encryption key for auth-context secrets:

    ```bash theme={null}
    openssl rand -base64 32
    ```
  </Step>

  <Step title="Start the node with PostgreSQL config">
    ```bash theme={null}
    SERVICENET_DATABASE_URL=postgres://servicenet:password@localhost:5432/watt-servicenet \
    SERVICENET_DATABASE_SCHEMA=public \
    SERVICENET_SECRET_BROKER_KEY=$(openssl rand -base64 32) \
    cargo run -p watt-servicenet-node
    ```
  </Step>
</Steps>

### Docker Compose

The included `docker-compose.yml` wires up a PostgreSQL 16 container alongside the ServiceNet node. Use it as a reference for your own deployment:

```yaml theme={null}
services:
  postgres:
    image: postgres:16
    environment:
      POSTGRES_USER: servicenet
      POSTGRES_PASSWORD: servicenet
      POSTGRES_DB: watt-servicenet
    ports:
      - "55433:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U servicenet -d watt-servicenet"]
      interval: 5s
      timeout: 5s
      retries: 12
    volumes:
      - ./.data/postgres:/var/lib/postgresql/data

  servicenet:
    build:
      context: .
      dockerfile: Dockerfile
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      SERVICENET_DATABASE_URL: postgres://servicenet:servicenet@postgres:5432/watt-servicenet
      SERVICENET_DATABASE_SCHEMA: public
      SERVICENET_HTTP_ADDR: 0.0.0.0:8042
      SERVICENET_REQUIRE_PROVIDER_OWNERSHIP_CHALLENGES: "1"
      SERVICENET_SECRET_BROKER_KEY: "<your-generated-key>"
    ports:
      - "8042:8042"
    volumes:
      - ./.data:/data
```

Start the full stack with:

```bash theme={null}
docker compose up --build
```

<Warning>
  Replace `<your-generated-key>` with a real key generated by `openssl rand -base64 32`. Do not commit a real key to source control — inject it via your secrets manager or a `.env` file excluded from version control.
</Warning>

### Running PostgreSQL Integration Tests

To run the integration test suite against a local PostgreSQL instance:

```bash theme={null}
SERVICENET_TEST_DATABASE_URL=postgres://servicenet:servicenet@127.0.0.1:55433/servicenet \
cargo test
```

<Note>
  PostgreSQL mode automatically enables provider ownership challenges (`SERVICENET_REQUIRE_PROVIDER_OWNERSHIP_CHALLENGES=1`). Auth-context secret storage is only available in PostgreSQL mode and always requires `SERVICENET_SECRET_BROKER_KEY`.
</Note>

## Switching Backends

You can switch backends between restarts, but note:

* **In-memory → file or PostgreSQL**: no migration needed; the node starts with an empty registry in the new backend.
* **File → PostgreSQL**: existing JSON file data is not automatically migrated to PostgreSQL. You must re-register providers and agents against the new backend.
* **PostgreSQL → file or in-memory**: existing PostgreSQL data is not accessible from the other backends.

For all production deployments, choose PostgreSQL from the start to avoid data migration.
