# `Jido.Storage.Redis`
[🔗](https://github.com/agentjido/jido/blob/v2.3.0/lib/jido/storage/redis.ex#L1)

Redis-based storage adapter for agent checkpoints and thread journals.

Durable storage suitable when you already operate Redis and want an
optional external backing store for Jido. The adapter does not depend
on a Redis client; callers provide a 1-arity `:command_fn`.

## Usage

    defmodule MyApp.RedisStorage do
      def command(cmd), do: Redix.command(:my_redis, cmd)
    end

    defmodule MyApp.Jido do
      use Jido,
        otp_app: :my_app,
        storage: {Jido.Storage.Redis, [
          command_fn: &MyApp.RedisStorage.command/1,
          prefix: "jido"
        ]}
    end

## Options

- `:command_fn` (required) — A function that executes Redis commands.
  Signature: `fn [binary()] -> {:ok, term()} | {:error, term()}`
  This keeps Redis client choice in the caller.
- `:prefix` (optional, default `"jido"`) — Key prefix for namespacing.
- `:ttl` (optional) — TTL in milliseconds for all keys. When set, keys
  expire automatically.

## Key Layout

    {prefix}:cp:{hex_hash}   → Serialized checkpoint
    {prefix}:th:{thread_id}  → Serialized thread state

Thread journals are stored as a single serialized value containing
revision, timestamps, metadata, and entries. Using one key avoids
partial writes between thread entries and metadata.

## Concurrency

Thread operations use `:global.trans/3` for distributed locking, matching
the pattern used by `Jido.Storage.ETS` and `Jido.Storage.File`.

# `opts`

```elixir
@type opts() :: keyword()
```

# `stored_thread`

```elixir
@type stored_thread() :: %{
  rev: non_neg_integer(),
  created_at: integer(),
  updated_at: integer(),
  metadata: map(),
  entries: [Jido.Thread.Entry.t()]
}
```

