# `Redis`
[🔗](https://github.com/joshrotenberg/redis_ex/blob/v0.7.1/lib/redis.ex#L1)

Modern, full-featured Redis client for Elixir.

This module provides the top-level API for single-connection usage.
For other deployment modes and features, see:

  * `Redis.Connection` - single connection with full options
  * `Redis.Connection.Pool` - connection pooling
  * `Redis.Cluster` - cluster-aware client with slot routing
  * `Redis.Sentinel` - sentinel-aware client with failover
  * `Redis.PubSub` - pub/sub subscriptions
  * `Redis.PhoenixPubSub` - Phoenix.PubSub adapter
  * `Redis.Cache` - client-side caching with ETS
  * `Redis.Consumer` - streams consumer group GenServer
  * `Redis.JSON` - high-level JSON document API
  * `Redis.Search` - high-level search API (Meilisearch-inspired)
  * `Redis.PlugSession` - Plug session store
  * `Redis.Resilience` - composed retry, circuit breaker, bulkhead
  * `Redis.Script` - Lua script execution with SHA caching
  * `Redis.Commands` - 21 command builder modules

## Quick Start

    {:ok, conn} = Redis.start_link()
    {:ok, "OK"} = Redis.command(conn, ["SET", "key", "value"])
    {:ok, "value"} = Redis.command(conn, ["GET", "key"])

## Pipelining

    {:ok, results} = Redis.pipeline(conn, [
      ["SET", "a", "1"],
      ["SET", "b", "2"],
      ["MGET", "a", "b"]
    ])

## Transactions

    {:ok, [1, 2, 3]} = Redis.transaction(conn, [
      ["INCR", "counter"],
      ["INCR", "counter"],
      ["INCR", "counter"]
    ])

## Optimistic Locking

    Redis.watch_transaction(conn, ["balance"], fn conn ->
      {:ok, bal} = Redis.command(conn, ["GET", "balance"])
      new_bal = String.to_integer(bal) + 100
      [["SET", "balance", to_string(new_bal)]]
    end)

# `conn`

```elixir
@type conn() :: GenServer.server()
```

# `child_spec`

Returns a child spec for supervision trees.

# `command`

```elixir
@spec command(conn(), [String.t()], keyword()) :: {:ok, term()} | {:error, term()}
```

Sends a single command.

# `command!`

```elixir
@spec command!(conn(), [String.t()], keyword()) :: term()
```

Sends a single command, raises on error.

# `noreply_command`

```elixir
@spec noreply_command(conn(), [String.t()], keyword()) :: :ok | {:error, term()}
```

Sends a command without waiting for a reply (CLIENT REPLY OFF/ON).

# `noreply_pipeline`

```elixir
@spec noreply_pipeline(conn(), [[String.t()]], keyword()) :: :ok | {:error, term()}
```

Sends multiple commands without waiting for replies.

# `pipeline`

```elixir
@spec pipeline(conn(), [[String.t()]], keyword()) ::
  {:ok, [term()]} | {:error, term()}
```

Sends multiple commands in a single pipeline.

# `start_link`

```elixir
@spec start_link(keyword() | String.t()) :: GenServer.on_start()
```

Starts a connection. Accepts a keyword list or a Redis URI string.

# `transaction`

```elixir
@spec transaction(conn(), [[String.t()]], keyword()) ::
  {:ok, [term()]} | {:error, term()}
```

Executes commands in a MULTI/EXEC transaction.

# `watch_transaction`

```elixir
@spec watch_transaction(
  conn(),
  [String.t()],
  (conn() -&gt; [[String.t()]] | {:abort, term()}),
  keyword()
) ::
  {:ok, [term()]} | {:error, term()}
```

Executes a WATCH-based optimistic locking transaction.

Watches the given keys, calls `fun` to read values and build commands,
then executes in MULTI/EXEC. Retries automatically on conflict.

    Redis.watch_transaction(conn, ["balance"], fn conn ->
      {:ok, bal} = Redis.command(conn, ["GET", "balance"])
      new_bal = String.to_integer(bal) + 100
      [["SET", "balance", to_string(new_bal)]]
    end)

---

*Consult [api-reference.md](api-reference.md) for complete listing*
