Persistence unstable
Stores encoded results for Persistable requests.
The Persistence service creates scoped stores keyed by each request's
PrimaryKey. Stores read and write schema-encoded Exit values with
optional TTLs, letting request workflows reuse expensive or idempotent results
across fibers, process restarts, or workers that share a backing store.
Converting
unsafeTtlToExpires
unstableConverts a TTL to an absolute expiration timestamp in milliseconds.
Details
Returns null for no TTL and uses clock.currentTimeMillisUnsafe, so it is
intended for backing-store internals.
Signature
declare function unsafeTtlToExpires(clock: Clock, ttl: Duration | undefined): number | nullErrors
PersistenceError
unstableError raised by persistence and backing-store operations.
Signature
declare class PersistenceError extends { readonly _tag: "PersistenceError"; readonly cause?: unknown; readonly message: string;} & YieldableError<this> { constructor(...args: [props: { readonly _tag?: "PersistenceError"; readonly cause?: unknown; readonly message: string; }, options?: MakeOptions]); readonly "~effect/persistence/Persistence/PersistenceError": "~effect/persistence/Persistence/PersistenceError";}Layers
Provides Persistence from BackingPersistence.
Details
The layer serializes and deserializes Persistable exits, applies
per-entry TTLs, and skips writes whose TTL is zero or negative.
Signature
declare const layer: Layer<Persistence, never, BackingPersistence>layerBackingKvs
unstableProvides BackingPersistence using a KeyValueStore.
Details
Entries are stored under <storeId>:<key>, with % and : in the store id
percent-encoded so store namespaces cannot overlap. Values are stored as JSON
with optional expiration timestamps.
clear uses KeyValueStore.clearPrefix to remove only the store's entries,
so the backing store must support it.
Signature
declare const layerBackingKvs: Layer.Layer<BackingPersistence, never, KeyValueStore.KeyValueStore>layerBackingMemory
unstableProvides an in-memory BackingPersistence grouped by store id.
Details
Entries are process-local and expire according to their stored TTL.
Signature
declare const layerBackingMemory: Layer.Layer<BackingPersistence>layerBackingRedis
unstableProvides Redis-backed persistence.
Details
Entries are stored under <storeId>:<key>, with % and : in the store id
percent-encoded so store namespaces cannot overlap. Values are JSON-encoded,
finite TTLs are stored with Redis expiration, and clear only removes keys
in the store's namespace.
Signature
declare const layerBackingRedis: Layer.Layer<BackingPersistence, never, Redis.Redis>layerBackingSql
unstableProvides SQL-backed persistence using a shared effect_persistence table.
Details
Rows are partitioned by store_id and store JSON-encoded values with
optional expiration timestamps.
Signature
declare const layerBackingSql: Layer.Layer<BackingPersistence, never, SqlClient.SqlClient>layerBackingSqlMultiTable
unstableProvides SQL-backed persistence using one table per store id.
Details
Each table is created if needed and stores JSON-encoded values with optional expiration timestamps.
Gotchas
Store ids are used directly in effect_persistence_${storeId} table names,
without encoding or collision detection. Choose ids whose full table names
are distinct under the database's identifier rules:
- Do not use dots: they are interpreted as schema separators.
- Do not rely on case alone to distinguish stores: SQLite treats ASCII-case
variants such as
Usersandusersas the same table. - Stay within the database's identifier length limit, including the prefix. PostgreSQL normally truncates identifiers to 63 bytes, leaving 44 bytes for the store id. Ids sharing those first 44 bytes can alias the same table.
Aliased stores share entries: writes can overwrite another store's values,
and clearing one clears the other. For arbitrary store ids, prefer
layerBackingSql, which stores ids as row values rather than table names.
See
- layerBackingSql
Signature
declare const layerBackingSqlMultiTable: Layer.Layer<BackingPersistence, never, SqlClient.SqlClient>Provides Persistence backed by the current KeyValueStore.
Signature
declare const layerKvs: Layer.Layer<Persistence, never, KeyValueStore.KeyValueStore>layerMemory
unstableProvides Persistence backed by process-local in-memory storage.
Signature
declare const layerMemory: Layer.Layer<Persistence>layerRedis
unstableProvides Persistence backed by the current Redis service.
Signature
declare const layerRedis: Layer.Layer<Persistence, never, Redis.Redis>Provides Persistence backed by SQL using a shared persistence table.
Signature
declare const layerSql: Layer.Layer<Persistence, never, SqlClient.SqlClient>layerSqlMultiTable
unstableProvides Persistence backed by SQL with one table per store id.
Gotchas
Store ids become effect_persistence_${storeId} table names and must obey
the database's identifier rules. Avoid dots, case-only distinctions, and
names exceeding the database's identifier length limit (including the
prefix). Colliding names share data, including writes and clears.
Prefer layerSql for arbitrary store ids.
See
- layerBackingSqlMultiTable for database-specific store-id restrictions
- layerSql
Signature
declare const layerSqlMultiTable: Layer.Layer<Persistence, never, SqlClient.SqlClient>Models
Typed store for persisted Exit values keyed by Persistable requests.
Signature
interface PersistenceStore { readonly clear: Effect<void, PersistenceError>; readonly get: <A extends Constraint, E extends Constraint>(key: Persistable<A, E>) => Effect<Exit<A["Type"], E["Type"]> | undefined, SchemaError | PersistenceError, A["DecodingServices"] | E["DecodingServices"]>; readonly getMany: <A extends Constraint, E extends Constraint>(keys: Iterable<Persistable<A, E>>) => Effect<Array<Exit<A["Type"], E["Type"]> | undefined>, SchemaError | PersistenceError, A["DecodingServices"] | E["DecodingServices"]>; readonly remove: <A extends Constraint, E extends Constraint>(key: Persistable<A, E>) => Effect<void, PersistenceError>; readonly set: <A extends Constraint, E extends Constraint>(key: Persistable<A, E>, value: Exit<A["Type"], E["Type"]>) => Effect<void, SchemaError | PersistenceError, A["EncodingServices"] | E["EncodingServices"]>; readonly setMany: <A extends Constraint, E extends Constraint>(entries: Iterable<readonly [Persistable<A, E>, Exit<A["Type"], E["Type"]>]>) => Effect<void, SchemaError | PersistenceError, A["EncodingServices"] | E["EncodingServices"]>;}Services
BackingPersistence
unstableService for creating raw backing stores for persistence store ids.
Signature
declare class BackingPersistence extends Shape<"effect/persistence/BackingPersistence", { readonly make: (storeId: string) => Effect<BackingPersistenceStore, never, Scope>;}, this> { constructor(_: never);}Raw persistence backing store for JSON-compatible objects with optional TTLs.
Signature
interface BackingPersistenceStore { readonly clear: Effect<void, PersistenceError>; readonly get: (key: string) => Effect<object | undefined, PersistenceError>; readonly getMany: (keys: [string, ...Array<string>]) => Effect<[object | undefined, ...Array<object | undefined>], PersistenceError>; readonly remove: (key: string) => Effect<void, PersistenceError>; readonly set: (key: string, value: object, ttl: Duration | undefined) => Effect<void, PersistenceError>; readonly setMany: (entries: [readonly [string, object, Duration | undefined], ...Array<readonly [string, object, Duration | undefined]>]) => Effect<void, PersistenceError>;}Persistence
unstableService for creating scoped stores of persisted Persistable request
results.
Signature
declare class Persistence extends Shape<"effect/persistence/Persistence", { readonly make: (options: { readonly storeId: string; readonly timeToLive?: (exit: Exit<unknown, unknown>, key: Any) => Input; }) => Effect<PersistenceStore, never, Scope>;}, this> { constructor(_: never);}