---
title: Storage Adapters
description: Configure SQLite, Postgres, S3, and P2P adapters for Persist stores.
section: Persist
order: 2
updatedAt: 2026-05-12
slug: persist/adapters
---
# Storage Adapters

Persist uses pluggable adapters for storage backends. Every adapter exposes the same API (`store.records`, `store.kv`, `store.blobs`, `store.events`), so you can swap backends without changing application code.

## SQLite

The default adapter. Ideal for local-first apps, development, and mobile.

```ts
import { createStore } from "@cuitty/persist";

const store = await createStore({
  name: "my-app",
  adapter: "sqlite",
  path: "./data/my-app.db",
});
```

SQLite stores are single-file, need no external process, and support WAL mode for concurrent reads out of the box.

## Postgres

Production-grade durability with full SQL support. Best for server-side workloads.

```ts
const store = await createStore({
  name: "my-app",
  adapter: "postgres",
  connection: {
    host: "localhost",
    port: 5432,
    database: "persist",
    user: "persist",
    password: process.env.PG_PASSWORD,
  },
});
```

### Connection pooling

Pass `pool: { max: 20 }` to control the connection pool size. The default is 10.

## S3

Blob storage adapter for large files and binary data.

```ts
const store = await createStore({
  name: "my-app",
  adapter: "s3",
  bucket: "my-persist-bucket",
  region: "us-east-1",
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
  },
});
```

The S3 adapter maps `store.blobs` operations to S3 objects and `store.records` to JSON objects stored under a configurable prefix.

## P2P

Peer-to-peer replication with no central server. Peers discover each other and sync directly.

```ts
const store = await createStore({
  name: "my-app",
  adapter: "p2p",
  discovery: {
    method: "mdns",         // or "dht" for wide-area
    topic: "my-app-sync",
  },
});
```

The P2P adapter uses CRDTs internally to merge writes from multiple peers without conflicts.

## Custom adapters

Implement the `PersistAdapter` interface to build your own backend.

```ts
import type { PersistAdapter } from "@cuitty/persist";

const myAdapter: PersistAdapter = {
  async get(key: string) { /* ... */ },
  async put(key: string, value: unknown) { /* ... */ },
  async delete(key: string) { /* ... */ },
  async list(prefix: string) { /* ... */ },
};

const store = await createStore({
  name: "my-app",
  adapter: myAdapter,
});
```

All four methods must return promises. `list` returns an async iterable of `{ key, value }` pairs.