Choose your
storage.
Keep a consistent document API.
Choose storage based on persistence, sharing, and query needs.
| Capability | Memory | FileSystem | Redis | PostgreSQL |
|---|---|---|---|---|
| Documents live in | Process memory | Memory + JSON file | Redis | PostgreSQL |
| Persistence | Temporary | Periodic save (~5s) | Write-through¹ | Committed writes |
| Shared across instances | No | No | Yes | Yes |
| Index lifetime | Until unload | Rebuilt on reload | Persisted in Redis | Persisted in PostgreSQL |
| Atomic batches | Yes | Yes, saved immediately | Yes | Yes |
¹ Redis persistence and eviction configuration determine durability. FileSystem uses one database owner per file; call Save() to flush explicitly.
Memory
For temporary data, tests, and applications that don’t need storage to survive a restart. No external service to configure.
Package on NuGet ↗dotnet add package Soenneker.Librarian.Memory
using Soenneker.Librarian.Memory.Registrars;
builder.Services.AddMemoryLibrarianDatabaseAsSingleton();
Scoped registrations are also available. A scoped memory database owns its own data.
FileSystem
In-memory access with a JSON file behind it. Designed for a single database owner, with periodic saves and immediate persistence for atomic batches.
Await database.Save() for an explicit flush. Dispose the database’s owner asynchronously to complete shutdown persistence.
dotnet add package Soenneker.Librarian.FileSystem
using Soenneker.Librarian.FileSystem.Registrars;
builder.Services.AddFileSystemLibrarianDatabaseAsSingleton();
{
"Librarian": {
"FileSystem": { "FilePath": "data/librarian.json" }
}
}
Redis
Shared documents and persisted indexes for multiple application instances. Reads fetch current Redis data; writes update documents and indexes together.
No RedisJSON, Redis Search, or Lua required. Use a non-evicting database; cluster deployments require Redis 8 or later.
Redis setup & guarantees ↗dotnet add package Soenneker.Librarian.Redis
using Soenneker.Librarian.Redis.Registrars;
builder.Services.AddRedisLibrarianDatabaseAsSingleton();
{
"Azure": { "Redis": { "ConnectionString": "localhost:6379" } },
"Librarian": {
"Redis": { "Key": "my-app:librarian" }
}
}
PostgreSQL
Shared persistent documents with SQL-backed filtering, sorting, paging, and aggregates. Writes and conditional batches commit immediately.
Indexes persist across restarts. Requires PostgreSQL 16 or later. Supply connection credentials through your application’s secret configuration.
PostgreSQL setup & queries ↗dotnet add package Soenneker.Librarian.Postgres
using Soenneker.Librarian.Postgres.Registrars;
builder.Services.AddPostgresLibrarianDatabaseAsSingleton();
Configure Librarian:Postgres:ConnectionString and Librarian:Postgres:Key.
Same API. Know the differences.
Memory and FileSystem can fall back to local evaluation for unsupported queries. Redis and PostgreSQL throw NotSupportedException. Review query support before moving a workload between providers.
Compare query capabilities ↗