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

# Persistence

> Storage adapters for persisting embeddings between restarts

Avoid re-indexing on every boot by using storage adapters. VectoriaDB supports file, Redis, and in-memory storage.

## Storage Adapters

| Adapter                | Use Case                 | Persistence    |
| ---------------------- | ------------------------ | -------------- |
| `MemoryStorageAdapter` | Development, testing     | None (default) |
| `FileStorageAdapter`   | Single-server deployment | Local disk     |
| `RedisStorageAdapter`  | Multi-pod deployment     | Shared cache   |

<Tabs>
  <Tab title="File Adapter">
    Persist embeddings to local disk:

    ```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
    import { VectoriaDB, FileStorageAdapter, SerializationUtils } from 'vectoriadb';

    const documents = collectToolDocuments();

    const toolIndex = new VectoriaDB<ToolDocument>({
      storageAdapter: new FileStorageAdapter({
        cacheDir: './.cache/vectoriadb',
        namespace: 'tool-index',
      }),
      toolsHash: SerializationUtils.createToolsHash(documents),
      version: process.env.npm_package_version,
    });

    await toolIndex.initialize();

    if (toolIndex.size() === 0) {
      await toolIndex.addMany(documents);
      await toolIndex.saveToStorage(); // Persist to disk
    }
    ```

    ### File Adapter Options

    | Option      | Type   | Default               | Description               |
    | ----------- | ------ | --------------------- | ------------------------- |
    | `cacheDir`  | string | `./.cache/vectoriadb` | Directory for cache files |
    | `namespace` | string | `'default'`           | Namespace for isolation   |
  </Tab>

  <Tab title="Redis Adapter">
    For multi-pod environments, use Redis to share embeddings:

    ```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
    import { VectoriaDB, RedisStorageAdapter } from 'vectoriadb';
    import Redis from 'ioredis';

    const redisClient = new Redis();

    const toolIndex = new VectoriaDB<ToolDocument>({
      storageAdapter: new RedisStorageAdapter({
        client: redisClient,
        namespace: 'tool-index',
        ttl: 86400,        // 24 hours (default)
        keyPrefix: 'vectoriadb',
      }),
    });

    await toolIndex.initialize();

    if (toolIndex.size() === 0) {
      await toolIndex.addMany(documents);
      await toolIndex.saveToStorage();
    }
    ```

    ### Redis Adapter Options

    | Option      | Type   | Default        | Description             |
    | ----------- | ------ | -------------- | ----------------------- |
    | `client`    | Redis  | required       | ioredis client instance |
    | `namespace` | string | `'default'`    | Namespace for isolation |
    | `ttl`       | number | `86400`        | Time-to-live in seconds |
    | `keyPrefix` | string | `'vectoriadb'` | Redis key prefix        |
  </Tab>

  <Tab title="Memory Adapter">
    No persistence - embeddings are lost on restart:

    ```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
    import { VectoriaDB, MemoryStorageAdapter } from 'vectoriadb';

    const toolIndex = new VectoriaDB<ToolDocument>({
      storageAdapter: new MemoryStorageAdapter({ namespace: 'tools' }),
    });
    ```

    Use for development or when re-indexing is fast enough.
  </Tab>
</Tabs>

## Cache Invalidation

VectoriaDB automatically invalidates the cache when documents change. Use `toolsHash` and `version` to control invalidation:

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const toolIndex = new VectoriaDB<ToolDocument>({
  storageAdapter: new FileStorageAdapter({ cacheDir: './.cache' }),

  // Hash of document contents - invalidates when documents change
  toolsHash: SerializationUtils.createToolsHash(documents),

  // Application version - invalidates on deployments
  version: process.env.npm_package_version,
});
```

### How Invalidation Works

On `initialize()`, VectoriaDB checks:

1. Does the cache file/key exist?
2. Does `toolsHash` match?
3. Does `version` match?
4. Does `modelName` match?

If any check fails, the cache is invalidated and re-indexing occurs.

## Warm-up Pattern

Common pattern for production deployments:

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
export async function warmToolIndex(documents: ToolDocument[]) {
  const toolIndex = new VectoriaDB<ToolDocument>({
    storageAdapter: new FileStorageAdapter({
      cacheDir: './.cache/vectoriadb',
      namespace: 'tool-index',
    }),
    toolsHash: SerializationUtils.createToolsHash(documents),
    version: process.env.npm_package_version,
  });

  await toolIndex.initialize();

  // Only re-index if cache was invalidated
  if (toolIndex.size() === 0) {
    console.log('Cache miss - re-indexing...');
    await toolIndex.addMany(documents);
    await toolIndex.saveToStorage();
  } else {
    console.log('Cache hit - loaded from storage');
  }

  return toolIndex;
}
```

## Manual Storage Operations

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
// Save current state to storage
await toolIndex.saveToStorage();

// Load from storage (done automatically on initialize)
await toolIndex.loadFromStorage();

// Clear storage
await toolIndex.clearStorage();
```

## Multi-Tenant Isolation

Use namespaces to isolate different indexes:

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
// Tenant A
const tenantAIndex = new VectoriaDB({
  storageAdapter: new RedisStorageAdapter({
    client: redisClient,
    namespace: 'tenant-a',
  }),
});

// Tenant B
const tenantBIndex = new VectoriaDB({
  storageAdapter: new RedisStorageAdapter({
    client: redisClient,
    namespace: 'tenant-b',
  }),
});
```

## Error Handling

```ts theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
import { StorageError } from 'vectoriadb';

try {
  await toolIndex.saveToStorage();
} catch (error) {
  if (error instanceof StorageError) {
    console.error('Storage operation failed:', error.message);
    // Fallback to in-memory only
  }
}
```

## Related

<CardGroup cols={3}>
  <Card title="Overview" icon="house" href="/vectoriadb/introduction">
    Getting started
  </Card>

  <Card title="HNSW" icon="chart-network" href="/vectoriadb/guides/hnsw">
    Scaling with HNSW index
  </Card>

  <Card title="Indexing" icon="plus" href="/vectoriadb/guides/indexing">
    Adding documents
  </Card>
</CardGroup>
