# How to Configure Persistent FlexSearch Indexes with Redis for Distributed Search Applications

> Learn to configure persistent FlexSearch indexes with Redis. Effortlessly share index state across multiple application instances using the Redis storage adapter for robust distributed search.

- Repository: [Nextapps GmbH/flexsearch](https://github.com/nextapps-de/flexsearch)
- Tags: how-to-guide
- Published: 2026-02-23

---

**Use the Redis storage adapter (`flexsearch/db/redis`) to persist FlexSearch indexes to a Redis server, enabling multiple application instances to share the same index state through a common namespace-based key schema and atomic transactions.**

FlexSearch is a high-performance full-text search library that typically operates in memory. When building distributed search applications, you need to configure persistent indexes with Redis to share state across multiple nodes. The `nextapps-de/flexsearch` repository provides a pluggable storage layer with a Redis adapter that implements the full storage interface, allowing you to run horizontally-scaled search services where every node reads from and writes to a common Redis instance or cluster.

## Architecture of the Redis Persistence Layer

The Redis adapter in [`src/db/redis/index.js`](https://github.com/nextapps-de/flexsearch/blob/main/src/db/redis/index.js) bridges FlexSearch's in-memory engine with external storage. The architecture consists of four main components:

- **FlexSearch Core** ([`src/index.js`](https://github.com/nextapps-de/flexsearch/blob/main/src/index.js), [`src/document.js`](https://github.com/nextapps-de/flexsearch/blob/main/src/document.js)): The in-memory search engine that builds inverted maps, document caches, and tag sets.
- **Redis Storage Adapter** ([`src/db/redis/index.js`](https://github.com/nextapps-de/flexsearch/blob/main/src/db/redis/index.js)): Implements the FlexSearch storage interface (`open`, `close`, `get`, `set`, `search`, `tag`, `remove`, `clear`) and persists internal maps to Redis.
- **Redis Server/Cluster**: Central key/value store where each index entry is stored under a namespaced key (e.g., `<prefix>|map:field`, `<prefix>|doc`). The adapter uses Redis commands (`HMSET`, `SADD`, `GET`, `KEYS`, `UNLINK`) to read and write these structures.
- **Application Instances**: Multiple FlexSearch instances running with the same Redis configuration, sharing or isolating indexes through unique prefixes.

### Key Implementation Details

The adapter uses several mechanisms to ensure data integrity and performance:

1. **Namespace-based key schema**: Every index uses a prefix (default `flexsearch`) to prevent collisions. Keys follow patterns like `flexsearch|map:field`, `flexsearch|doc`, and `flexsearch|cfg`【/cache/repos/github.com/nextapps-de/flexsearch/master/doc/persistent-redis.md#L81-L93】.

2. **Auto-commit**: After each mutating operation (`add`, `update`, `remove`), the adapter writes changes to Redis automatically. You can await explicit durability with `await index.commit()`【/cache/repos/github.com/nextapps-de/flexsearch/master/doc/persistent-redis.md#L36-L40】.

3. **Custom Redis client support**: Pass a pre-configured Redis client via the `db` option to use clustering, TLS, or custom retry strategies【/cache/repos/github.com/nextapps-de/flexsearch/master/doc/persistent-redis.md#L48-L58】.

4. **ID type handling**: Redis stores all values as strings. The adapter enforces ID types (`integer`, `string`) so lookups return correctly typed identifiers【/cache/repos/github.com/nextapps-de/flexsearch/master/doc/persistent-redis.md#L62-L71】.

5. **Transaction abstraction**: Write operations are wrapped in Redis transactions (`MULTI/EXEC`) in [`src/db/redis/index.js`](https://github.com/nextapps-de/flexsearch/blob/main/src/db/redis/index.js) to guarantee atomicity across multiple keys forming one logical update.

## Setting Up Redis Persistence in FlexSearch

Follow these steps to configure persistent indexes with Redis for your distributed application.

### Install Dependencies

Install FlexSearch and the Redis client in your Node.js application:

```bash
npm install flexsearch@latest redis@4.7.0

```

### Configure the Redis Client

Create a shared Redis client to handle clustering, TLS, or connection pooling:

```javascript
import { createClient } from "redis";

const redis = await createClient({
    socket: {
        host: "redis.example.com",
        port: 6379,
        // tls: { /* TLS options */ }
    }
}).connect();

```

### Mount the Redis Database

Instantiate your FlexSearch index and mount the Redis storage adapter:

```javascript
import { Index } from "flexsearch";
import Database from "flexsearch/db/redis";

const index = new Index({
    // FlexSearch options: tokenizer, encode, etc.
});

const db = new Database("shared-search", {
    db: redis,           // Reuse the custom client
    type: "integer"      // Enforce numeric IDs
});

await index.mount(db);

```

### Perform CRUD Operations

Any node in your distributed system can now modify the shared index:

```javascript
// Add a document
await index.add(101, "Node.js performance tips");

// Update
await index.update(101, "Advanced Node.js performance tips");

// Search from any instance
const results = await index.search("performance");
console.log(results); // [101, ...]

// Remove
await index.remove(101);

```

### Graceful Shutdown

Close connections properly when terminating your application:

```javascript
await db.close(); // Or await index.unmount()

```

## Distributed Search Example

Here is a complete worker implementation that multiple instances can run to create a horizontally-scaled search API:

```javascript
// worker.js
import http from "http";
import { Index } from "flexsearch";
import Database from "flexsearch/db/redis";
import { createClient } from "redis";

const redis = await createClient({ url: "redis://localhost:6379" }).connect();

const index = new Index();
await index.mount(new Database("search-api", { db: redis }));

http.createServer(async (req, res) => {
    const url = new URL(req.url, `http://${req.headers.host}`);
    
    if (url.pathname === "/add") {
        const id = Number(url.searchParams.get("id"));
        const text = url.searchParams.get("text");
        await index.add(id, text);
        res.end("added");
    } else if (url.pathname === "/search") {
        const q = url.searchParams.get("q");
        const hits = await index.search(q);
        res.end(JSON.stringify(hits));
    } else {
        res.statusCode = 404;
        res.end("not found");
    }
}).listen(3000);

```

Run several instances of this worker on different ports or containers. All instances share the same Redis-backed index, enabling true distributed search where a document added by one instance can be searched by any other instance instantly.

## Summary

- **Use the Redis adapter** (`flexsearch/db/redis`) to persist FlexSearch indexes to a Redis server, enabling shared state across distributed application instances.
- **Namespace isolation** prevents key collisions when running multiple indexes on the same Redis instance using configurable prefixes like `shared-search|map:field`.
- **Atomic transactions** via Redis `MULTI/EXEC` ensure data integrity across the multiple keys that constitute a single index operation, as implemented in [`src/db/redis/index.js`](https://github.com/nextapps-de/flexsearch/blob/main/src/db/redis/index.js).
- **Custom client support** allows integration with Redis clusters, TLS connections, and custom retry strategies by passing a pre-configured client to the `db` option.
- **Auto-commit with explicit control** ensures durability after each mutation, with `await index.commit()` available for synchronous durability guarantees before proceeding.

## Frequently Asked Questions

### Can I use Redis Cluster with FlexSearch?

Yes. Pass a pre-configured Redis Cluster client via the `db` option when instantiating the Database. The adapter uses standard Redis commands (`HMSET`, `SADD`, `GET`, `KEYS`, `UNLINK`) that are compatible with Redis Cluster, allowing you to distribute your index across multiple Redis nodes for higher availability and throughput【/cache/repos/github.com/nextapps-de/flexsearch/master/doc/persistent-redis.md#L48-L58】.

### How does FlexSearch handle ID types when storing data in Redis?

Redis stores all values as strings, but FlexSearch allows you to enforce specific ID types using the `type` option when creating the Database. Set `type: "integer"` to ensure that document IDs returned from searches are converted to numbers, or use `type: "string"` to keep them as strings. This type enforcement happens in the Redis adapter's serialization layer【/cache/repos/github.com/nextapps-de/flexsearch/master/doc/persistent-redis.md#L62-L71】.

### What happens if the Redis connection fails during an indexing operation?

The Redis adapter wraps write operations in Redis transactions (`MULTI/EXEC`) to ensure atomicity. If the connection fails during a transaction, Redis will discard the partial changes, preventing index corruption. The adapter implemented in [`src/db/redis/index.js`](https://github.com/nextapps-de/flexsearch/blob/main/src/db/redis/index.js) handles connection management, and you can pass a custom client with retry strategies via the `db` option to implement automatic reconnection logic for transient network failures.

### Can multiple applications share the same Redis index while keeping some indexes isolated?

Yes. Use the namespace prefix (the first argument to `new Database()`) to isolate indexes. For example, create one Database with `new Database("app-a-index", { db: redis })` and another with `new Database("app-b-index", { db: redis })`. Each prefix creates a separate keyspace in Redis (e.g., `app-a-index|map:field` vs `app-b-index|map:field`), allowing complete isolation while sharing the same Redis server【/cache/repos/github.com/nextapps-de/flexsearch/master/doc/persistent-redis.md#L81-L93】.