title: AI Agent Resources

summary: Learn how to develop with Redis as an AI agent

page_type: content

title: `llms.txt` index of documentation

role: overview

text: Redis provides a comprehensive index of all documentation in Markdown format at [llms.txt](https://redis.io/llms.txt). This index is specifically designed for AI agents to discover available documentation.

title: Markdown documentation format

role: content

text:
All documentation pages are available in Markdown format via the same URL as
the main doc page but with `index.html.md` added. For example, the Markdown version of
this page is available at
[ai-agent-resources/index.html.md](https://redis.io/docs/latest/ai-agent-resources/index.html.md).

title: JSON documentation feeds

text: Redis documentation is available in structured JSON format optimized for RAG (Retrieval-Augmented Generation) systems.

title: NDJSON feed (all pages)

text:
A single file containing all documentation pages in [NDJSON](https://github.com/ndjson/ndjson-spec) format (one JSON object per line):

| Format | URL | Size |
|--------|-----|------|
| NDJSON | [docs.ndjson](https://redis.io/docs/latest/docs.ndjson) | ~30 MB |
| Gzipped | [docs.ndjson.gz](https://redis.io/docs/latest/docs.ndjson.gz) | ~5 MB |

Both files contain ~4,100 documents.

title: Per-page JSON

text:
Each documentation page has a corresponding JSON file at the same URL with `/index.json` appended. For example:

- Page: `https://redis.io/docs/latest/commands/set/`
- JSON: `https://redis.io/docs/latest/commands/set/index.json`

title: JSON schema

text:
Each document contains:

| Field | Type | Description |
|-------|------|-------------|
| `id` | string | URL slug identifier |
| `title` | string | Page title |
| `url` | string | Canonical URL |
| `summary` | string | Short description |
| `page_type` | string | `"content"` (has prose) or `"index"` (navigation only) |
| `content_hash` | string | SHA256 hash for cache invalidation (content pages only) |
| `sections` | array | Content split by headings with semantic roles |
| `examples` | array | Code blocks extracted from content |
| `children` | array | Child pages (index pages only) |

Each **section** contains:
- `id`: Slugified heading
- `title`: Original heading text
- `role`: Semantic role (`overview`, `syntax`, `example`, `parameters`, `returns`, etc.)
- `text`: Section content (code blocks replaced with `[code example]` placeholder)

Each **example** contains:
- `id`: Unique identifier (`{section_id}-ex{index}`)
- `language`: Language from code fence (`python`, `go`, `plaintext`, etc.)
- `code`: The code content
- `section_id`: Which section this example came from

title: Verifying content_hash

text:
The `content_hash` can be verified by computing:

[code example]

title: API references

text:
API references are available for the following client libraries:

- [redis-py](https://redis.readthedocs.io/en/stable/commands.html)
- [jedis](https://javadoc.io/doc/redis.clients/jedis/latest/index.html)
- [lettuce](https://lettuce.io/core/release/reference/index.html)
- [go-redis](https://pkg.go.dev/github.com/redis/go-redis/v9)
- [redis-rs](https://docs.rs/redis/latest/redis/)

title: Data type comparisons

text:
See [Compare data types]() for advice
on which of the general-purpose data types is best for common tasks.

title: Redis patterns for coding agents

text: Salvatore Sanfilippo (also known as *antirez*, the creator of Redis) has provided the Redis community with a resource containing very useful Redis-oriented design patterns. See [this page](https://redis.antirez.com/) for more information.

title: Error handling

role: errors

text: See [Error handling]() for a guide to handling errors in client libraries.

code:
import hashlib

def verify_hash(page):
    parts = [page.get('summary', '')]
    for section in page.get('sections', []):
        parts.append(section['text'])
    for example in page.get('examples', []):
        parts.append(example['code'])

    content = '\n'.join(parts)
    return hashlib.sha256(content.encode('utf-8')).hexdigest() == page.get('content_hash')

section_id: verifying-content-hash


title: APIs

summary: An overview of Redis APIs for developers and operators

title: Overview

text: Redis provides a number of APIs for developers and operators. The following sections provide you easy access to the client API, the several programmability APIs, the RESTFul management APIs and the Kubernetes resource definitions.

title: APIs for Developers

title: Client API

text:
Redis comes with a wide range of commands that help you to develop real-time applications. You can find a complete overview of the Redis commands here:

- [Redis commands]()

As a developer, you will likely use one of our supported client libraries for connecting and executing commands.

- [Connect with Redis clients introduction]()

title: Programmability APIs

text:
The existing Redis commands cover most use cases, but if low latency is a critical requirement, you might need to extend Redis' server-side functionality.

Lua scripts have been available since early versions of Redis. With Lua, the script is provided by the client and cached on the server side, which implies the risk that different clients might use a different script version.

- [Redis Lua API reference]()
- [Scripting with Lua introduction]()

The Redis functions feature, which became available in Redis 7, supersedes the use of Lua in prior versions of Redis. The client is still responsible for invoking the execution, but unlike the previous Lua scripts, functions can now be replicated and persisted.

- [Functions and scripting in Redis 7 and beyond]()

If none of the previous methods fulfills your needs, then you can extend the functionality of Redis with new commands using the Redis Modules API.

- [Redis Modules API introduction]()
- [Redis Modules API reference]()

title: APIs for Operators

title: Redis Cloud API

text:
Redis Cloud is a fully managed Database as a Service offering and the fastest way to deploy Redis at scale. You can programmatically manage your databases, accounts, access, and credentials using the Redis Cloud REST API.

- [Redis Cloud REST API introduction]()
- [Redis Cloud REST API examples]()
- [Redis Cloud REST API reference]()

title: Redis Software API

text:
If you have installed Redis Software, you can automate operations with the Redis Software REST API.

- [Redis Software REST API introduction]()
- [Redis Software REST API requests]()
- [Redis Software REST API objects]()

title: Redis Enterprise for Kubernetes API

text:
If you need to install Redis Enterprise on Kubernetes, then you can use the [Redis Enterprise for Kubernetes Operators](). You can find the resource definitions here:

- [Redis Enterprise Cluster API]()
- [Redis Enterprise Database API]()


title: ACL

summary: A container for Access List Control commands.

title: Content

text:
This is a container command for [Access Control List]() commands.

To see the list of available commands you can call [`ACL HELP`]().


title: ACL CAT

summary: Lists the ACL categories, or the commands inside a category.

title: Overview

text:
The command shows the available ACL categories if called without arguments.
If a category name is given, the command shows all the Redis commands in
the specified category.

ACL categories are very useful in order to create ACL rules that include or
exclude a large set of commands at once, without specifying every single
command. For instance, the following rule will let the user `karin` perform
everything but the most dangerous operations that may affect the server
stability:

    ACL SETUSER karin on +@all -@dangerous

We first add all the commands to the set of commands that `karin` is able
to execute, but then we remove all the dangerous commands.

Checking for all the available categories is as simple as:

[code example]

Then we may want to know what commands are part of a given category:

[code example]

title: Redis Software and Redis Cloud compatibility

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ✅ Standard
<nobr>✅ Active-Active</nobr> | ✅ Standard
<nobr>✅ Active-Active</nobr> | Not supported for [scripts](). |

title: Return information

role: returns

text:
**RESP2:**

One of the following:
* [Array reply](../../develop/reference/protocol-spec#arrays): an array of [Bulk string reply](../../develop/reference/protocol-spec#bulk-strings) elements representing ACL categories or commands in a given category.
* [Simple error reply](../../develop/reference/protocol-spec#simple-errors): the command returns an error if an invalid category name is given.

**RESP3:**

One of the following:
* [Array reply](../../develop/reference/protocol-spec#arrays): an array of [Bulk string reply](../../develop/reference/protocol-spec#bulk-strings) elements representing ACL categories or commands in a given category.
* [Simple error reply](../../develop/reference/protocol-spec#simple-errors): the command returns an error if an invalid category name is given.

code:
> ACL CAT
 1) "keyspace"
 2) "read"
 3) "write"
 4) "set"
 5) "sortedset"
 6) "list"
 7) "hash"
 8) "string"
 9) "bitmap"
10) "hyperloglog"
11) "geo"
12) "stream"
13) "pubsub"
14) "admin"
15) "fast"
16) "slow"
17) "blocking"
18) "dangerous"
19) "connection"
20) "transaction"
21) "scripting"
22) "json"
23) "search"
24) "tdigest"
25) "cms"
26) "bloom"
27) "cuckoo"
28) "topk"
29) "timeseries"

section_id: overview

code:
> ACL CAT dangerous
 1) "flushdb"
 2) "acl"
 3) "slowlog"
 4) "debug"
 5) "role"
 6) "keys"
 7) "pfselftest"
 8) "client"
 9) "bgrewriteaof"
10) "replicaof"
11) "monitor"
12) "restore-asking"
13) "latency"
14) "replconf"
15) "pfdebug"
16) "bgsave"
17) "sync"
18) "config"
19) "flushall"
20) "cluster"
21) "info"
22) "lastsave"
23) "slaveof"
24) "swapdb"
25) "module"
26) "restore"
27) "migrate"
28) "save"
29) "shutdown"
30) "psync"
31) "sort"


title: ACL DELUSER

summary: Deletes ACL users, and terminates their connections.

title: Overview

text:
Delete all the specified ACL users and terminate all the connections that are
authenticated with such users. Note: the special `default` user cannot be
removed from the system, this is the default user that every new connection
is authenticated with. The list of users may include usernames that do not
exist, in such case no operation is performed for the non existing users.

title: Examples

role: example

text: [code example]

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ❌ Standard
<nobr>❌ Active-Active</nobr> | ❌ Standard
<nobr>❌ Active-Active</nobr> |  |

title: Return information

text:
**RESP2:**

[Integer reply](../../develop/reference/protocol-spec#integers): the number of users that were deleted. This number will not always match the number of arguments since certain users may not exist.

**RESP3:**

[Integer reply](../../develop/reference/protocol-spec#integers): the number of users that were deleted. This number will not always match the number of arguments since certain users may not exist.

code:
> ACL DELUSER antirez
1

section_id: examples


title: ACL DRYRUN

summary: Simulates the execution of a command by a user, without executing the command.

title: Overview

text:
Simulate the execution of a given command by a given user.
This command can be used to test the permissions of a given user without having to enable the user or cause the side effects of running the command.

title: Examples

text: [code example]

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ✅ Standard
<nobr>✅ Active-Active</nobr> | ✅ Standard
<nobr>✅ Active-Active</nobr> | Might reply with "unknown user" for LDAP users even if `AUTH` succeeds. |

title: Return information

text:
**RESP2:**

Any of the following:
* [Simple string reply](../../develop/reference/protocol-spec#simple-strings): `OK` on success.
* [Bulk string reply](../../develop/reference/protocol-spec#bulk-strings): an error describing why the user can't execute the command.

**RESP3:**

Any of the following:
* [Simple string reply](../../develop/reference/protocol-spec#simple-strings): `OK` on success.
* [Bulk string reply](../../develop/reference/protocol-spec#bulk-strings): an error describing why the user can't execute the command.

code:
> ACL SETUSER VIRGINIA +SET ~*
"OK"
> ACL DRYRUN VIRGINIA SET foo bar
"OK"
> ACL DRYRUN VIRGINIA GET foo
"User VIRGINIA has no permissions to run the 'get' command"


title: ACL GENPASS

summary: Generates a pseudorandom, secure password that can be used to identify ACL users.

title: Overview

text:
ACL users need a solid password in order to authenticate to the server without
security risks. Such password does not need to be remembered by humans, but
only by computers, so it can be very long and strong (unguessable by an
external attacker). The `ACL GENPASS` command generates a password starting
from /dev/urandom if available, otherwise (in systems without /dev/urandom) it
uses a weaker system that is likely still better than picking a weak password
by hand.

By default (if /dev/urandom is available) the password is strong and
can be used for other uses in the context of a Redis application, for
instance in order to create unique session identifiers or other kind of
unguessable and not colliding IDs. The password generation is also very cheap
because we don't really ask /dev/urandom for bits at every execution. At
startup Redis creates a seed using /dev/urandom, then it will use SHA256
in counter mode, with HMAC-SHA256(seed,counter) as primitive, in order to
create more random bytes as needed. This means that the application developer
should be feel free to abuse `ACL GENPASS` to create as many secure
pseudorandom strings as needed.

The command output is a hexadecimal representation of a binary string.
By default it emits 256 bits (so 64 hex characters). The user can provide
an argument in form of number of bits to emit from 1 to 1024 to change
the output length. Note that the number of bits provided is always
rounded to the next multiple of 4. So for instance asking for just 1
bit password will result in 4 bits to be emitted, in the form of a single
hex character.

title: Examples

text: [code example]

title: Return information

text:
**RESP2:**

[Bulk string reply](../../develop/reference/protocol-spec#bulk-strings): pseudorandom data. By default it contains 64 bytes, representing 256 bits of data. If `bits` was given, the output string length is the number of specified bits (rounded to the next multiple of 4) divided by 4.

**RESP3:**

[Bulk string reply](../../develop/reference/protocol-spec#bulk-strings): pseudorandom data. By default it contains 64 bytes, representing 256 bits of data. If `bits` was given, the output string length is the number of specified bits (rounded to the next multiple of 4) divided by 4.

code:
> ACL GENPASS
"dd721260bfe1b3d9601e7fbab36de6d04e2e67b0ef1c53de59d45950db0dd3cc"

> ACL GENPASS 32
"355ef3dd"

> ACL GENPASS 5
"90"


title: ACL GETUSER

summary: Lists the ACL rules of a user.

title: Overview

text:
The command returns all the rules defined for an existing ACL user.

Specifically, it lists the user's ACL flags, password hashes, commands, key patterns, channel patterns (Added in version 6.2) and selectors (Added in version 7.0).
Additional information may be returned in the future if more metadata is added to the user.

Command rules are always returned in the same format as the one used in the [`ACL SETUSER`]() command.
Before version 7.0, keys and channels were returned as an array of patterns, however in version 7.0 later they are now also returned in same format as the one used in the [`ACL SETUSER`]() command.
Note: This description of command rules reflects the user's effective permissions, so while it may not be identical to the set of rules used to configure the user, it is still functionally identical.

Selectors are listed in the order they were applied to the user, and include information about commands, key patterns, and channel patterns.

title: Examples

text:
Here's an example configuration for a user

[code example]

title: Return information

text:
**RESP2:**

One of the following:
* [Array reply](../../develop/reference/protocol-spec#arrays): a list of ACL rule definitions for the user.
* [Nil reply](../../develop/reference/protocol-spec#bulk-strings): if user does not exist.

**RESP3:**

One of the following:
* [Map reply](../../develop/reference/protocol-spec#maps): a set of ACL rule definitions for the user
* [Null reply](../../develop/reference/protocol-spec#nulls): if user does not exist.

code:
> ACL SETUSER sample on nopass +GET allkeys &* (+SET ~key2)
"OK"
> ACL GETUSER sample
1) "flags"
2) 1) "on"
   2) "allkeys"
   3) "nopass"
3) "passwords"
4) (empty array)
5) "commands"
6) "+@all"
7) "keys"
8) "~*"
9) "channels"
10) "&*"
11) "selectors"
12) 1) 1) "commands"
       6) "+SET"
       7) "keys"
       8) "~key2"
       9) "channels"
       10) "&*"


title: ACL HELP

summary: Returns helpful text about the different subcommands.

title: Overview

text: The `ACL HELP` command returns a helpful text describing the different subcommands.

title: Return information

text:
**RESP2:**

[Array reply](../../develop/reference/protocol-spec#arrays): a list of subcommands and their descriptions.

**RESP3:**

[Array reply](../../develop/reference/protocol-spec#arrays): a list of subcommands and their descriptions.


title: ACL LIST

summary: Dumps the effective rules in ACL file format.

title: Overview

text:
The command shows the currently active ACL rules in the Redis server. Each
line in the returned array defines a different user, and the format is the
same used in the redis.conf file or the external ACL file, so you can
cut and paste what is returned by the ACL LIST command directly inside a
configuration file if you wish (but make sure to check [`ACL SAVE`]()).

title: Examples

text:
[code example]

In some cases, you might see `allchannels` instead of `&*` and `allkeys` instead of `~*` in the output. This is because `allchannels` and `allkeys` are aliases for `&*` and `~*` respectively.

title: Return information

text:
**RESP2:**

[Array reply](../../develop/reference/protocol-spec#arrays): an array of [Bulk string reply](../../develop/reference/protocol-spec#bulk-strings) elements.

**RESP3:**

[Array reply](../../develop/reference/protocol-spec#arrays): an array of [Bulk string reply](../../develop/reference/protocol-spec#bulk-strings) elements.

code:
> ACL LIST
1) "user antirez on #9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08 ~objects:* &* +@all -@admin -@dangerous"
2) "user default on nopass ~* &* +@all"


title: ACL LOAD

summary: Reloads the rules from the configured ACL file.

title: Overview

text:
When Redis is configured to use an ACL file (with the `aclfile` configuration
option), this command will reload the ACLs from the file, replacing all
the current ACL rules with the ones defined in the file. The command makes
sure to have an *all or nothing* behavior, that is:

* If every line in the file is valid, all the ACLs are loaded.
* If one or more line in the file is not valid, nothing is loaded, and the old ACL rules defined in the server memory continue to be used.

title: Examples

text: [code example]

title: Return information

text:
**RESP2:**

[Simple string reply](../../develop/reference/protocol-spec#simple-strings): `OK` on success.
The command may fail with an error for several reasons: if the file is not readable, if there is an error inside the file, and in such cases, the error will be reported to the user in the error.
Finally, the command will fail if the server is not configured to use an external ACL file.

**RESP3:**

[Simple string reply](../../develop/reference/protocol-spec#simple-strings): `OK` on success.
The command may fail with an error for several reasons: if the file is not readable, if there is an error inside the file, and in such cases, the error will be reported to the user in the error.
Finally, the command will fail if the server is not configured to use an external ACL file.

code:
> ACL LOAD
+OK

> ACL LOAD
-ERR /tmp/foo:1: Unknown command or category name in ACL...


title: ACL LOG

summary: Lists recent security events generated due to ACL rules.

title: Overview

text:
The command shows a list of recent ACL security events:

1. Failed authentications with [`AUTH`]() or [`HELLO`]() (reason = auth)
2. Commands violating the current ACL rules
   - Disallowed commands (reason = command).
   - Disallowed keys (reason = key).
   - Disallowed pub/sub channel (reason = channel).

The optional argument specifies how many entries to show. By default
up to ten failures are returned. The special [`RESET`]() argument clears the log.
Entries are displayed starting from the most recent.

title: Examples

text:
[code example]

Each log entry is composed of the following fields:

1. `count`: The number of security events detected within a 60 second period that are represented by this entry.
2. `reason`: The reason that the security events were logged. Either `command`, `key`, `channel`, or `auth`.
3. `context`: The context that the security events were detected in. Either `toplevel`, `multi`, `lua`, or `module`.
4. `object`: The resource that the user had insufficient permissions to access. `auth` when the reason is `auth`.
5. `username`: The username that executed the command that caused the security events or the username that had a failed authentication attempt.
6. `age-seconds`: Age of the log entry in seconds.
7. `client-info`: Displays the client info of a client which caused one of the security events.
8. `entry-id`: The sequence number of the entry (starting at 0) since the server process started. Can also be used to check if items were "lost", if they fell between periods.
9. `timestamp-created`: A UNIX timestamp in `milliseconds` at the time the entry was first created.
10. `timestamp-last-updated`: A UNIX timestamp in `milliseconds` at the time the entry was last updated.

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ❌ Standard
<nobr>❌ Active-Active</nobr> | ❌ Standard
<nobr>❌ Active-Active</nobr> |  |

title: Return information

text:
**RESP2:**

When called to show security events:
* [Array reply](../../develop/reference/protocol-spec#arrays): an array of [Bulk string reply](../../develop/reference/protocol-spec#bulk-strings) elements representing ACL security events.
When called with `RESET`:
* [Simple string reply](../../develop/reference/protocol-spec#simple-strings): `OK` if the security log was cleared.

**RESP3:**

When called to show security events:
* [Array reply](../../develop/reference/protocol-spec#arrays): an array of [Bulk string reply](../../develop/reference/protocol-spec#bulk-strings) elements representing ACL security events.
When called with `RESET`:
* [Simple string reply](../../develop/reference/protocol-spec#simple-strings): `OK` if the security log was cleared.

code:
> AUTH someuser wrongpassword
(error) WRONGPASS invalid username-password pair
> ACL LOG 1
1)  1) "count"
    2) (integer) 1
    3) "reason"
    4) "auth"
    5) "context"
    6) "toplevel"
    7) "object"
    8) "AUTH"
    9) "username"
   10) "someuser"
   11) "age-seconds"
   12) "8.038"
   13) "client-info"
   14) "id=3 addr=127.0.0.1:57275 laddr=127.0.0.1:6379 fd=8 name= age=16 idle=0 flags=N db=0 sub=0 psub=0 ssub=0 multi=-1 qbuf=48 qbuf-free=16842 argv-mem=25 multi-mem=0 rbs=1024 rbp=0 obl=0 oll=0 omem=0 tot-mem=18737 events=r cmd=auth user=default redir=-1 resp=2"
   15) "entry-id"
   16) (integer) 0
   17) "timestamp-created"
   18) (integer) 1675361492408
   19) "timestamp-last-updated"
   20) (integer) 1675361492408


title: ACL SAVE

summary: Saves the effective ACL rules in the configured ACL file.

title: Overview

text:
When Redis is configured to use an ACL file (with the `aclfile` configuration
option), this command will save the currently defined ACLs from the server memory to the ACL file.

title: Examples

text: [code example]

title: Return information

text:
**RESP2:**

[Simple string reply](../../develop/reference/protocol-spec#simple-strings): `OK`.
The command may fail with an error for several reasons: if the file cannot be written or if the server is not configured to use an external ACL file.

**RESP3:**

[Simple string reply](../../develop/reference/protocol-spec#simple-strings): `OK`.
The command may fail with an error for several reasons: if the file cannot be written or if the server is not configured to use an external ACL file.

code:
> ACL SAVE
+OK

> ACL SAVE
-ERR There was an error trying to save the ACLs. Please check the server logs for more information


title: ACL SETUSER

summary: Creates and modifies an ACL user and its rules.

title: Overview

text:
Create an ACL user with the specified rules or modify the rules of an
existing user.

Manipulate Redis ACL users interactively.
If the username does not exist, the command creates the username without any privilege.
It then reads from left to right all the [rules](#acl-rules) provided as successive arguments, setting the user ACL rules as specified.
If the user already exists, the provided ACL rules are simply applied
*in addition* to the rules already set. For example:

    ACL SETUSER virginia on allkeys +set

The above command creates a user called `virginia` who is active(the _on_ rule), can access any key (_allkeys_ rule), and can call the set command (_+set_ rule).
Then, you can use another `ACL SETUSER` call to modify the user rules:

    ACL SETUSER virginia +get

The above rule applies the new rule to the user `virginia`, so other than [`SET`](), the user `virginia` can now also use the [`GET`]() command.

Starting from Redis 7.0, ACL rules can also be grouped into multiple distinct sets of rules, called _selectors_.
Selectors are added by wrapping the rules in parentheses and providing them just like any other rule.
In order to execute a command, either the root permissions (rules defined outside of parenthesis) or any of the selectors (rules defined inside parenthesis) must match the given command.
For example:

    ACL SETUSER virginia on +GET allkeys (+SET ~app1*)

This sets a user with two sets of permissions, one defined on the user and one defined with a selector.
The root user permissions only allow executing the get command, but can be executed on any keys.
The selector then grants a secondary set of permissions: access to the [`SET`]() command to be executed on any key that starts with `app1`.
Using multiple selectors allows you to grant permissions that are different depending on what keys are being accessed.

When we want to be sure to define a user from scratch, without caring if
it had previously defined rules associated, we can use the special rule
`reset` as first rule, in order to flush all the other existing rules:

    ACL SETUSER antirez reset [... other rules ...]

After resetting a user, its ACL rules revert to the default: inactive, passwordless, can't execute any command nor access any key or channel:

    > ACL SETUSER antirez reset
    +OK
    > ACL LIST
    1) "user antirez off -@all"

ACL rules are either words like "on", "off", "reset", "allkeys", or are
special rules that start with a special character, and are followed by
another string (without any space in between), like "+SET".

For information on persisting ACLs, see the [ACL tutorial](#use-an-external-acl-file).

The following documentation is a reference manual about the capabilities of this command, however our [ACL tutorial]() may be a more gentle introduction to how the ACL system works in general.

title: ACL rules

role: security

text:
Redis ACL rules are split into two categories: rules that define command permissions or _command rules_, and rules that define the user state or _user management rules_.
This is a list of all the supported Redis ACL rules:

title: Command rules

role: syntax

text:
* `~<pattern>`: Adds the specified key pattern (glob style pattern, like in the [`KEYS`]() command), to the list of key patterns accessible by the user. This grants both read and write permissions to keys that match the pattern. You can add multiple key patterns to the same user. Example: `~objects:*`
* `%R~<pattern>`: (Available in Redis 7.0 and later) Adds the specified read key pattern. This behaves similar to the regular key pattern but only grants permission to read from keys that match the given pattern. See [key permissions]() for more information.
* `%W~<pattern>`: (Available in Redis 7.0 and later) Adds the specified write key pattern. This behaves similar to the regular key pattern but only grants permission to write to keys that match the given pattern. See [key permissions]() for more information.
* `%RW~<pattern>`: (Available in Redis 7.0 and later) Alias for `~<pattern>`.
* `allkeys`: Alias for `~*`, it allows the user to access all the keys.
* `resetkeys`: Removes all the key patterns from the list of key patterns the user can access.
* `&<pattern>`: (Available in Redis 6.2 and later) Adds the specified glob style pattern to the list of Pub/Sub channel patterns accessible by the user. You can add multiple channel patterns to the same user. Example: `&chatroom:*`
* `allchannels`: Alias for `&*`, it allows the user to access all Pub/Sub channels.
* `resetchannels`: Removes all channel patterns from the list of Pub/Sub channel patterns the user can access.
* `+<command>`: Adds the command to the list of commands the user can call. Can be used with `|` for allowing subcommands (e.g "+config|get").
* `+@<category>`: Adds all the commands in the specified category to the list of commands the user is able to execute. Example: `+@string` (adds all the string commands). For a list of categories, check the [`ACL CAT`]() command.
* `+<command>|first-arg`: Allows a specific first argument of an otherwise disabled command. It is only supported on commands with no sub-commands, and is not allowed as negative form like -SELECT|1, only additive starting with "+". This feature is deprecated and may be removed in the future.
* `allcommands`: Alias of `+@all`. Adds all the commands there are in the server, including *future commands* loaded via module, to be executed by this user.
* `-<command>`: Remove the command to the list of commands the user can call. Starting Redis 7.0, it can be used with `|` for blocking subcommands (e.g., "-config|set").
* `-@<category>`: Like `+@<category>` but removes all the commands in the category instead of adding them.
* `nocommands`: Alias for `-@all`. Removes all the commands, and the user is no longer able to execute anything.

title: User management rules

text:
* `on`: Set the user as active, it will be possible to authenticate as this user using `AUTH <username> <password>`.
* `off`: Set user as not active, it will be impossible to log as this user. Please note that if a user gets disabled (set to off) after there are connections already authenticated with such a user, the connections will continue to work as expected. To also kill the old connections you can use [`CLIENT KILL`]() with the user option. An alternative is to delete the user with [`ACL DELUSER`](), that will result in all the connections authenticated as the deleted user to be disconnected.
* `nopass`: The user is set as a _no password_ user. It means that it will be possible to authenticate as such user with any password. By default, the `default` special user is set as "nopass". The `nopass` rule will also reset all the configured passwords for the user.
* `>password`: Adds the specified clear text password as a hashed password in the list of the users passwords. Every user can have many active passwords, so that password rotation will be simpler. The specified password is not stored as clear text inside the server. Example: `>mypassword`.
* `#<hashedpassword>`: Adds the specified hashed password to the list of user passwords. A Redis hashed password is hashed with SHA256 and translated into a hexadecimal string. Example: `#c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2`.
* `<password`: Like `>password` but removes the password instead of adding it.
* `!<hashedpassword>`: Like `#<hashedpassword>` but removes the password instead of adding it.
* `(<rule list>)`: (Available in Redis 7.0 and later) Creates a new selector to match rules against. Selectors are evaluated after the user permissions, and are evaluated according to the order they are defined. If a command matches either the user permissions or any selector, it is allowed. See [selectors]() for more information.
* `clearselectors`: (Available in Redis 7.0 and later) Deletes all of the selectors attached to the user.
* `reset`: Removes any capability from the user. They are set to off, without passwords, unable to execute any command, unable to access any key.

title: Examples

text: [code example]

title: Return information

text:
**RESP2:**

[Simple string reply](../../develop/reference/protocol-spec#simple-strings): `OK`.
If the rules contain errors, the error is returned.

**RESP3:**

[Simple string reply](../../develop/reference/protocol-spec#simple-strings): `OK`.
If the rules contain errors, the error is returned.

code:
> ACL SETUSER alan allkeys +@string +@set -SADD >alanpassword
+OK

> ACL SETUSER antirez heeyyyy
(error) ERR Error in ACL SETUSER modifier 'heeyyyy': Syntax error


title: ACL USERS

summary: Lists all ACL users.

title: Overview

text:
The command shows a list of all the usernames of the currently configured
users in the Redis ACL system.

title: Examples

text: [code example]

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ✅ Standard
<nobr>✅ Active-Active</nobr> | ✅ Standard
<nobr>✅ Active-Active</nobr> | Not supported for [scripts](). |

title: Return information

text:
**RESP2:**

[Array reply](../../develop/reference/protocol-spec#arrays): list of existing ACL users.

**RESP3:**

[Array reply](../../develop/reference/protocol-spec#arrays): list of existing ACL users.

code:
> ACL USERS
1) "anna"
2) "antirez"
3) "default"


title: ACL WHOAMI

summary: Returns the authenticated username of the current connection.

title: Overview

text:
Return the username the current connection is authenticated with.
New connections are authenticated with the "default" user. They
can change user using [`AUTH`]().

title: Examples

text: [code example]

title: Return information

text:
**RESP2:**

[Bulk string reply](../../develop/reference/protocol-spec#bulk-strings): the username of the current connection.

**RESP3:**

[Bulk string reply](../../develop/reference/protocol-spec#bulk-strings): the username of the current connection.

code:
> ACL WHOAMI
"default"


title: APPEND

summary: Appends a string to the value of a key. Creates the key if it doesn't exist.

title: Overview

text:
If `key` already exists and is a string, this command appends the `value` at the
end of the string.
If `key` does not exist it is created and set as an empty string, so `APPEND`
will be similar to [`SET`]() in this special case.

title: Examples

text:
EXISTS mykey
APPEND mykey "Hello"
APPEND mykey " World"
GET mykey

title: Pattern: Time series

text:
The `APPEND` command can be used to create a very compact representation of a
list of fixed-size samples, usually referred as _time series_.
Every time a new sample arrives we can store it using the command

[code example]

Accessing individual elements in the time series is not hard:

* [`STRLEN`]() can be used in order to obtain the number of samples.
* [`GETRANGE`]() allows for random access of elements.
  If our time series have associated time information we can easily implement
  a binary search to get range combining [`GETRANGE`]() with the Lua scripting
  engine available in Redis 2.6.
* [`SETRANGE`]() can be used to overwrite an existing time series.

The limitation of this pattern is that we are forced into an append-only mode
of operation, there is no way to cut the time series to a given size easily
because Redis currently lacks a command able to trim string objects.
However the space efficiency of time series stored in this way is remarkable.

Hint: it is possible to switch to a different key based on the current Unix
time, in this way it is possible to have just a relatively small amount of
samples per key, to avoid dealing with very big keys, and to make this pattern
more friendly to be distributed across many Redis instances.

An example sampling the temperature of a sensor using fixed-size strings (using
a binary format is better in real implementations).

APPEND ts "0043"
APPEND ts "0035"
GETRANGE ts 0 3
GETRANGE ts 4 7

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ✅ Standard
<nobr>✅ Active-Active</nobr> | ✅ Standard
<nobr>✅ Active-Active</nobr> |  |

title: Return information

text:
**RESP2:**

[Integer reply](../../develop/reference/protocol-spec#integers): the length of the string after the append operation.

**RESP3:**

[Integer reply](../../develop/reference/protocol-spec#integers): the length of the string after the append operation.

code: APPEND timeseries "fixed-size sample"

section_id: pattern-time-series


title: ASKING

summary: Signals that a cluster client is following an -ASK redirect.

title: Overview

text:
When a cluster client receives an `-ASK` redirect, the `ASKING` command is sent to the target node followed by the command which was redirected.
This is normally done automatically by cluster clients.

If an `-ASK` redirect is received during a transaction, only one ASKING command needs to be sent to the target node before sending the complete transaction to the target node.

See [ASK redirection in the Redis Cluster Specification]() for details.

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ❌ Standard
<nobr>❌ Active-Active</nobr> | ❌ Standard
<nobr>❌ Active-Active</nobr> |  |

title: Return information

text:
**RESP2:**

[Simple string reply](../../develop/reference/protocol-spec#simple-strings): `OK`.

**RESP3:**

[Simple string reply](../../develop/reference/protocol-spec#simple-strings): `OK`.


title: AUTH

summary: Authenticates the connection.

title: Security notice

text:
Because of the high performance nature of Redis, it is possible to try
a lot of passwords in parallel in very short time, so make sure to generate a
strong and very long password so that this attack is infeasible.
A good way to generate strong passwords is via the [`ACL GENPASS`]() command.

title: Return information

text:
**RESP2:**

[Simple string reply](../../develop/reference/protocol-spec#simple-strings): `OK`, or an error if the password, or username/password pair, is invalid.

**RESP3:**

[Simple string reply](../../develop/reference/protocol-spec#simple-strings): `OK`, or an error if the password, or username/password pair, is invalid.


title: BF.ADD

summary: Adds an item to a Bloom Filter

title: Overview

text:
Adds an item to a Bloom filter.

This command is similar to [`BF.MADD`](), except that only one item can be added.

title: Required arguments

text:
key

is key name for a Bloom filter to add the item to.

If `key` does not exist - a new Bloom filter is created with default error rate, capacity, and expansion (see [`BF.RESERVE`]()).

item

is an item to add.

title: Examples

text:
redis> BF.ADD bf item1
(integer) 1
redis> BF.ADD bf item1
(integer) 0

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ✅ Supported
 | <nobr>✅ Flexible & Annual</nobr>
✅ Free & Fixed</nobr> |  |

title: Return information

text:
**RESP2:**

One of the following:
* [Integer reply](): `1` for successfully adding an item, or `0` if there's a probability that the item was already added to the filter.
* [Simple error reply]() in these cases: invalid arguments, wrong key type, or when the filter is full.

**RESP3:**

One of the following:
* [Boolean reply](): `true` for successfully adding an item, or `false` if there's a probability that the item was already added to the filter.
* [Simple error reply]() in these cases: invalid arguments, wrong key type, or when the filter is full.


title: BF.CARD

title: Overview

text:
Returns the cardinality of a Bloom filter - number of items that were added to a Bloom filter and detected as unique (items that caused at least one bit to be set in at least one sub-filter)

(since RedisBloom 2.4.4)

title: Required arguments

text:
key

is key name for a Bloom filter.

title: Examples

text:
redis> BF.ADD bf1 item_foo
(integer) 1
redis> BF.CARD bf1
(integer) 1
redis> BF.CARD bf_new
(integer) 0

title: Return information

text:
**RESP2:**

One of the following:
* [Integer reply](): the number of items detected as unique that were added to the Bloom filter (items that caused at least one bit to be set in at least one sub-filter), or `0` when the given `key` does not exist.
* [Simple error reply]() in these cases: invalid arguments, wrong key type, or when the filter is full.

Note: when `key` exists, `BF.CARD` returns the same value as `BF.INFO key ITEMS`.

**RESP3:**

One of the following:
* [Integer reply](): the number of items detected as unique that were added to the Bloom filter (items that caused at least one bit to be set in at least one sub-filter), or `0` when the given `key` does not exist.
* [Simple error reply]() in these cases: invalid arguments, wrong key type, or when the filter is full.

Note: when `key` exists, `BF.CARD` returns the same value as `BF.INFO key ITEMS`.


title: BF.EXISTS

summary: Checks whether an item exists in a Bloom Filter

title: Overview

text:
Determines whether a given item was added to a Bloom filter.

This command is similar to [`BF.MEXISTS`](), except that only one item can be checked.

title: Required arguments

text:
key

is key name for a Bloom filter.

item

is an item to check.

title: Examples

text:
redis> BF.ADD bf item1
(integer) 1
redis> BF.EXISTS bf item1
(integer) 1
redis> BF.EXISTS bf item2
(integer) 0

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ✅ Supported
 | ✅ Flexible & Annual
✅ Free & Fixed</nobr> |  |

title: Return information

text:
**RESP2:**

One of the following:
* [Integer reply](): `1` means that, with high probability, `item` was already added to the filter, and `0` means that either the `key` does not exist or that the `item` had not been added to the filter.
* [Simple error reply]() if invalid arguments are passed.

**RESP3:**

One of the following:
* [Boolean reply](): `true` means that, with high probability, `item` was already added to the filter, and `false` means that either `key` does not exist or that `item` had not been added to the filter.
* [Simple error reply]() if invalid arguments are passed or `key` is not of the correct type.


title: BF.INFO

summary: Returns information about a Bloom Filter

title: Overview

text: Returns information about a Bloom filter.

title: Required arguments

text:
key

is key name for a Bloom filter.

title: Optional arguments

role: parameters

text:
CAPACITY

Return the number of unique items that can be stored in this Bloom filter before scaling would be required (including already added items).

SIZE

Return the memory size: number of bytes allocated for this Bloom filter.

FILTERS

Return the number of sub-filters.

ITEMS

Return the number of items that were added to this Bloom filter and detected as unique (items that caused at least one bit to be set in at least one sub-filter).

EXPANSION

Return the expansion rate.

title: Examples

text:
redis> BF.ADD bf1 observation1
(integer) 1
redis> BF.INFO bf1
 1) Capacity
 2) (integer) 100
 3) Size
 4) (integer) 240
 5) Number of filters
 6) (integer) 1
 7) Number of items inserted
 8) (integer) 1
 9) Expansion rate
10) (integer) 2
redis> BF.INFO bf1 CAPACITY
1) (integer) 100

title: Return information

text:
**RESP2:**

One of the following:
* A singleton [array reply]() with an [integer]() representing the value of the requested property.
* An [array reply]() with [simple string]() and [integer]() pairs.
* [Simple error reply]() in these cases: invalid arguments, wrong key type, or when the key does not exist.

**RESP3:**

One of the following:
* [Map reply]() with [simple string]() and [integer]() pairs.
* [Simple error reply]() in these cases: invalid arguments, wrong key type, or when the key does not exist.


title: BF.INSERT

summary: Adds one or more items to a Bloom Filter. A filter will be created if it does not exist

title: Overview

text:
Creates a new Bloom filter if the `key` does not exist using the specified error rate, capacity, and expansion, then adds all specified items to the Bloom Filter.

This command is similar to [`BF.MADD`](), except that the error rate, capacity, and expansion can be specified. It is a sugarcoated combination of [`BF.RESERVE`]() and [`BF.MADD`]().

title: Required arguments

text:
key

is key name for a Bloom filter to add items to.

If `key` does not exist, a new Bloom filter is created.

ITEMS item...

One or more items to add.

title: Optional arguments

text:
NOCREATE

Indicates that the filter should not be created if it does not already exist.
If the filter does not yet exist, an error is returned rather than creating it automatically.
This may be used where a strict separation between filter creation and filter addition is desired.
It is an error to specify `NOCREATE` together with either `CAPACITY` or `ERROR`.

CAPACITY capacity

Specifies the desired `capacity` for the filter to be created.
This parameter is ignored if the filter already exists.
If the filter is automatically created and this parameter is absent, then the module-level `capacity` is used.
See [`BF.RESERVE`]() for more information about the impact of this value.

ERROR error

Specifies the `error` ratio of the newly created filter if it does not yet exist.
If the filter is automatically created and `error` is not specified then the module-level error rate is used.
See [`BF.RESERVE`]() for more information about the format of this value.

NONSCALING

Prevents the filter from creating additional sub-filters if initial capacity is reached.
Non-scaling filters require slightly less memory than their scaling counterparts. The filter returns an error when `capacity` is reached.

EXPANSION expansion

When `capacity` is reached, an additional sub-filter is created.
The size of the new sub-filter is the size of the last sub-filter multiplied by `expansion`, specified as a positive integer.

If the number of elements to be stored in the filter is unknown, use an `expansion` of `2` or more to reduce the number of sub-filters.
Otherwise, use an `expansion` of `1` to reduce memory consumption. The default value is `2`.

title: Examples

text:
Add three items to a filter, then create the filter with default parameters if it does not already exist.

BF.INSERT filter ITEMS foo bar baz

Add one item to a filter, then create the filter with a capacity of 10000 if it does not already exist.

BF.INSERT filter CAPACITY 10000 ITEMS hello

Add two items to a filter, then return error if the filter does not already exist.

BF.INSERT filter NOCREATE ITEMS foo bar

title: Return information

text:
**RESP2:**

One of the following: where each element is one of these options:
* [Array reply](), where each element is one of the following options:
  * [Integer reply]() `1` for successfully adding an item, or `0` if there's a probability that the item was already added to the filter.
  * [Simple string reply]() when the item cannot be added because the filter is full.
* [Simple error reply]() when the number of arguments or key type is wrong, and also when `NOCREATE` is specified and `key` does not exist.

**RESP3:**

One of the following: where each element is one of these options:
* [Array reply](), where each element is one of the following options:
  * [Boolean reply]() `true` for successfully adding an item, or `false` if there's a probability that the item was already added to the filter.
  * [Simple string reply]() when the item cannot be added because the filter is full.
* [Simple error reply]() when the number of arguments or key type is wrong, and also when `NOCREATE` is specified and `key` does not exist.


title: BF.LOADCHUNK

summary: Restores a filter previously saved using SCANDUMP

title: Overview

text:
Restores a Bloom filter previously saved using [`BF.SCANDUMP`]().

See the [`BF.SCANDUMP`]() command for example usage.

<note><b>Notes</b>

- This command overwrites the Bloom filter stored under `key`.
- Make sure that the Bloom filter is not changed between invocations.

</note>

title: Required arguments

text:
key

is key name for a Bloom filter to restore.

iterator

Iterator value associated with `data` (returned by [`BF.SCANDUMP`]())

data

Current data chunk (returned by [`BF.SCANDUMP`]())

title: Examples

text: See [`BF.SCANDUMP`]() for an example.

title: Return information

text:
**RESP2:**

One of the following:
* [Simple string reply](): `OK` if executed correctly.
* [Simple error reply]() in these cases: invalid arguments, wrong key type, or when invalid data was passed.

**RESP3:**

One of the following:
* [Simple string reply](): `OK` if executed correctly.
* [Simple error reply]() in these cases: invalid arguments, wrong key type, or when invalid data was passed.


title: BF.MADD

title: Overview

text:
Adds one or more items to a Bloom filter.

This command is similar to [`BF.ADD`](), except that you can add more than one item.

This command is similar to [`BF.INSERT`](), except that the error rate, capacity, and expansion cannot be specified.

title: Required arguments

text:
key

is key name for a Bloom filter to add the items to.

If `key` does not exist - a new Bloom filter is created with default error rate, capacity, and expansion (see [`BF.RESERVE`]()).

item...

One or more items to add.

title: Return information

text:
Returns one of these replies:

- [Array reply]() where each element is either
  - [Integer reply]() - where "1" means that the item has been added successfully, and "0" means that such item was already added to the filter (which could be wrong)
  - [] when the item cannot be added because the filter is full
- [] on error (invalid arguments, wrong key type, etc.)

title: Examples

text:
redis> BF.MADD bf item1 item2 item2
1) (integer) 1
2) (integer) 1
3) (integer) 0

title: Return information

text:
**RESP2:**

One of the following:
* [Array reply]() where each element is either
  * an [integer reply](), where `1` means that the item has been added successfully, and `0` means there's a probability that the item was already added to the filter.
  * a [simple error reply]() when the item cannot be added because the filter is full.
* [Simple error reply]() in these cases: invalid arguments, key not found, wrong key type, or when the filter is full.

**RESP3:**

One of the following:
* [Array reply]() where each element is either
  * a [boolean reply](), where `true` means that the item has been added successfully, and `false` means there's a probability that the item was already added to the filter.
  * a [simple error reply]() when the item cannot be added because the filter is full.
* [Simple error reply]() in these cases: invalid arguments, key not found, wrong key type, or when the filter is full.


title: BF.MEXISTS

summary: Checks whether one or more items exist in a Bloom Filter

title: Overview

text:
Determines whether one or more items were added to a Bloom filter.

This command is similar to [`BF.EXISTS`](), except that more than one item can be checked.

title: Required arguments

text:
key

is key name for a Bloom filter.

item...

One or more items to check.

title: Examples

text:
redis> BF.MADD bf item1 item2
1) (integer) 1
2) (integer) 1
redis> BF.MEXISTS bf item1 item2 item3
1) (integer) 1
2) (integer) 1
3) (integer) 0

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ✅ Supported
 | ✅ Flexible & Annual
✅ Free & Fixed</nobr> |  |

title: Return information

text:
**RESP2:**

One of the following:
* [Array reply]() of [integer replies](), where `1` means that, with high probability, `item` was already added to the filter, and `0` means that `key` does not exist or that `item` was definitely not added to the filter.
* [Simple error reply]() in these cases: in these cases: invalid arguments, wrong key type, or when the key was not found.

**RESP3:**

One of the following:
* [Array reply]() of [boolean replies](), where `true` means that, with high probability, `item` was already added to the filter, and `false` means that `key` does not exist or that `item` was definitely not added to the filter.
* [Simple error reply]() in these cases: in these cases: invalid arguments, wrong key type, or when the key was not found.


title: BF.RESERVE

summary: Creates a new Bloom Filter

title: Overview

text:
Creates an empty Bloom filter with a single sub-filter for the initial specified capacity and with an upper bound `error_rate`.

By default, the filter auto-scales by creating additional sub-filters when `capacity` is reached.
The new sub-filter is created with size of the previous sub-filter multiplied by `expansion`.

Though the filter can scale up by creating sub-filters, it is recommended to reserve the estimated required `capacity` since maintaining and querying
sub-filters requires additional memory (each sub-filter uses an extra bits and hash function) and consume  further CPU time than an equivalent filter that had
the right capacity at creation time.

The optimal number of hash functions is `ceil(-ln(error_rate) / ln(2))`.

The required number of bits per item, given the desired `error_rate` and the optimal number of hash functions, is `-ln(error_rate) / ln(2)^2`. Hence, the required number of bits in the filter is `capacity * -ln(error_rate) / ln(2)^2`.

* **1%**    error rate requires  7 hash functions and  9.585 bits per item.
* **0.1%**  error rate requires 10 hash functions and 14.378 bits per item.
* **0.01%** error rate requires 14 hash functions and 19.170 bits per item.

title: Required arguments

text:
key

is key name for the the Bloom filter to be created.

error_rate

The desired probability for false positives. The rate is a decimal value between 0 and 1.
For example, for a desired false positive rate of 0.1% (1 in 1000), error_rate should be set to 0.001.

capacity

The number of entries intended to be added to the filter.
If your filter allows scaling, performance will begin to degrade after adding more items than this number.
The actual degradation depends on how far the limit has been exceeded. Performance degrades linearly with the number of `sub-filters`.

title: Optional arguments

text:
NONSCALING

Prevents the filter from creating additional sub-filters if initial capacity is reached.
Non-scaling filters requires slightly less memory than their scaling counterparts. The filter returns an error when `capacity` is reached.

EXPANSION expansion

When `capacity` is reached, an additional sub-filter is created.
The size of the new sub-filter is the size of the last sub-filter multiplied by `expansion`, specified as a positive integer.

If the number of items to be stored in the filter is unknown, you use an `expansion` of `2` or more to reduce the number of sub-filters.
Otherwise, you use an `expansion` of `1` to reduce memory consumption. The default value is `2`.

title: Examples

text:
redis> BF.RESERVE bf 0.01 1000
OK

redis> BF.RESERVE bf 0.01 1000
(error) ERR item exists

redis> BF.RESERVE bf_exp 0.01 1000 EXPANSION 2
OK

redis> BF.RESERVE bf_non 0.01 1000 NONSCALING
OK

title: Return information

text:
**RESP2:**

One of the following:
* [Simple string reply](): `OK` if the filter was created successfully.
* [Simple error reply]() in these cases: invalid arguments or the key already exists.

**RESP3:**

One of the following:
* [Simple string reply](): `OK` if the filter was created successfully.
* [Simple error reply]() in these cases: invalid arguments or the key already exists.


title: BF.SCANDUMP

summary: Begins an incremental save of the bloom filter

title: Overview

text:
Begins an incremental save of the Bloom filter.

This command is useful for large Bloom filters that cannot fit into the [`DUMP`]() and [`RESTORE`]() model.

The first time this command is called, the value of `iter` should be 0.

This command returns successive `(iter, data)` pairs until `(0, NULL)` to indicate completion.

title: Required arguments

text:
key

is key name for a Bloom filter to save.

iterator

Iterator value; either 0 or the iterator from a previous invocation of this command

title: Examples

text:
redis> BF.RESERVE bf 0.1 10
OK
redis> BF.ADD bf item1
1) (integer) 1
redis> BF.SCANDUMP bf 0
1) (integer) 1
2) "\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x02\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x9a\x99\x99\x99\x99\x99\xa9?J\xf7\xd4\x9e\xde\xf0\x18@\x05\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00"
redis> BF.SCANDUMP bf 1
1) (integer) 9
2) "\x01\b\x00\x80\x00\x04 \x00"
redis> BF.SCANDUMP bf 9
1) (integer) 0
2) ""
redis> DEL bf
(integer) 1
redis> BF.LOADCHUNK bf 1 "\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x02\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x9a\x99\x99\x99\x99\x99\xa9?J\xf7\xd4\x9e\xde\xf0\x18@\x05\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00"
OK
redis> BF.LOADCHUNK bf 9 "\x01\b\x00\x80\x00\x04 \x00"
OK
redis> BF.EXISTS bf item1
(integer) 1

Python code:

chunks = []
iter = 0
while True:
    iter, data = BF.SCANDUMP(key, iter)
    if iter == 0:
        break
    else:
        chunks.append([iter, data])

# Load it back
for chunk in chunks:
    iter, data = chunk
    BF.LOADCHUNK(key, iter, data)

title: Return information

text:
**RESP2:**

One of the following:
* [Array reply](): a two-element array of an [Integer reply]() (_Iterator_) and a [Bulk string reply]() (_Data_).
* [Simple error reply]() in these cases: invalid arguments, the key was not found, or the key is of the wrong type.

The Iterator is passed as input to the next invocation of `BF.SCANDUMP`. If _Iterator_ is 0, then it means iteration has completed.

The iterator-data pair should also be passed to [`BF.LOADCHUNK`]() when restoring the filter.

**RESP3:**

One of the following:
* [Array reply](): a two-element array of an [Integer reply]() (_Iterator_) and a [Bulk string reply]() (_Data_).
* [Simple error reply]() in these cases: invalid arguments, the key was not found, or the key is of the wrong type.

The Iterator is passed as input to the next invocation of `BF.SCANDUMP`. If _Iterator_ is 0, then it means iteration has completed.

The iterator-data pair should also be passed to [`BF.LOADCHUNK`]() when restoring the filter.


title: BGREWRITEAOF

summary: Asynchronously rewrites the append-only file to disk.

title: Overview

text:
Instruct Redis to start an [Append Only File](#append-only-file) rewrite process.
The rewrite will create a small optimized version of the current Append Only
File.

If `BGREWRITEAOF` fails, no data gets lost as the old AOF will be untouched.

The rewrite will be only triggered by Redis if there is not already a background
process doing persistence.

Specifically:

* If a Redis child is creating a snapshot on disk, the AOF rewrite is _scheduled_ but not started until the saving child producing the RDB file terminates. In this case the `BGREWRITEAOF` will still return a positive status reply, but with an appropriate message.  You can check if an AOF rewrite is scheduled looking at the [`INFO`]() command as of Redis 2.6 or successive versions.
* If an AOF rewrite is already in progress the command returns an error and no
  AOF rewrite will be scheduled for a later time.
* If the AOF rewrite could start, but the attempt at starting it fails (for instance because of an error in creating the child process), an error is returned to the caller.

Since Redis 2.4 the AOF rewrite is automatically triggered by Redis, however the
`BGREWRITEAOF` command can be used to trigger a rewrite at any time.

See the [persistence documentation]() for detailed information.

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ❌ Standard
<nobr>❌ Active-Active</nobr> | ❌ Standard
<nobr>❌ Active-Active</nobr> |  |

title: Return information

text:
**RESP2:**

[Simple string reply](../../develop/reference/protocol-spec#simple-strings): a simple string reply indicating that the rewriting started or is about to start ASAP when the call is executed with success.
The command may reply with an error in certain cases, as documented above.

**RESP3:**

[Bulk string reply](../../develop/reference/protocol-spec#bulk-strings): a simple string reply indicating that the rewriting started or is about to start ASAP when the call is executed with success.
The command may reply with an error in certain cases, as documented above.


title: BGSAVE

summary: Asynchronously saves the database(s) to disk.

title: Overview

text:
Save the DB in background.

Normally the OK code is immediately returned.
Redis forks, the parent continues to serve the clients, the child saves the DB
on disk then exits.

An error is returned if there is already a background save running or if there
is another non-background-save process running, specifically an in-progress AOF
rewrite.

If `BGSAVE SCHEDULE` is used, the command will immediately return `OK` when an
AOF rewrite is in progress and schedule the background save to run at the next
opportunity.

A client may be able to check if the operation succeeded using the [`LASTSAVE`]()
command.

See the [persistence documentation]() for detailed information.

title: Return information

text:
**RESP2:**

One of the following:
* [Simple string reply](../../develop/reference/protocol-spec#simple-strings): `Background saving started`.
* [Simple string reply](../../develop/reference/protocol-spec#simple-strings): `Background saving scheduled`.

**RESP3:**

One of the following:
* [Simple string reply](../../develop/reference/protocol-spec#simple-strings): `Background saving started`.
* [Simple string reply](../../develop/reference/protocol-spec#simple-strings): `Background saving scheduled`.


title: BITCOUNT

summary: Counts the number of set bits (population counting) in a string.

title: Overview

text:
Count the number of set bits (population counting) in a string.

By default all the bytes contained in the string are examined.
It is possible to specify the counting operation only in an interval passing the
additional arguments _start_ and _end_.

Like for the [`GETRANGE`]() command start and end can contain negative values in
order to index bytes starting from the end of the string, where -1 is the last
byte, -2 is the penultimate, and so forth.

Non-existent keys are treated as empty strings, so the command will return zero.

By default, the additional arguments _start_ and _end_ specify a byte index.
We can use an additional argument `BIT` to specify a bit index.
So 0 is the first bit, 1 is the second bit, and so forth.
For negative values, -1 is the last bit, -2 is the penultimate, and so forth.

title: Examples

text:
SET mykey "foobar"
BITCOUNT mykey
BITCOUNT mykey 0 0
BITCOUNT mykey 1 1
BITCOUNT mykey 1 1 BYTE
BITCOUNT mykey 5 30 BIT

title: Pattern: real-time metrics using bitmaps

text:
Bitmaps are a very space-efficient representation of certain kinds of
information.
One example is a Web application that needs the history of user visits, so that
for instance it is possible to determine what users are good targets of beta
features.

Using the [`SETBIT`]() command this is trivial to accomplish, identifying every day
with a small progressive integer.
For instance day 0 is the first day the application was put online, day 1 the
next day, and so forth.

Every time a user performs a page view, the application can register that in
the current day the user visited the web site using the [`SETBIT`]() command setting
the bit corresponding to the current day.

Later it will be trivial to know the number of single days the user visited the
web site simply calling the `BITCOUNT` command against the bitmap.

A similar pattern where user IDs are used instead of days is described
in the article called "[Fast easy realtime metrics using Redis
bitmaps][hbgc212fermurb]".

[hbgc212fermurb]: http://blog.getspool.com/2011/11/29/fast-easy-realtime-metrics-using-redis-bitmaps

title: Performance considerations

role: performance

text:
In the above example of counting days, even after 10 years the application is
online we still have just `365*10` bits of data per user, that is just 456 bytes
per user.
With this amount of data `BITCOUNT` is still as fast as any other O(1) Redis
command like [`GET`]() or [`INCR`]().

When the bitmap is big, there are two alternatives:

* Taking a separated key that is incremented every time the bitmap is modified.
  This can be very efficient and atomic using a small Redis Lua script.
* Running the bitmap incrementally using the `BITCOUNT` _start_ and _end_
  optional parameters, accumulating the results client-side, and optionally
  caching the result into a key.

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ✅ Standard
<nobr>✅ Active-Active</nobr> | ✅ Standard
<nobr>✅ Active-Active</nobr> |  |

title: Return information

text:
**RESP2:**

[Integer reply](../../develop/reference/protocol-spec#integers): the number of bits set to 1.

**RESP3:**

[Integer reply](../../develop/reference/protocol-spec#integers): the number of bits set to 1.


title: BITFIELD

summary: Performs arbitrary bitfield integer operations on strings.

title: Overview

text:
The command treats a Redis string as an array of bits, and is capable of addressing specific integer fields of varying bit widths and arbitrary non (necessary) aligned offset. In practical terms using this command you can set, for example, a signed 5 bits integer at bit offset 1234 to a specific value, retrieve a 31 bit unsigned integer from offset 4567. Similarly the command handles increments and decrements of the specified integers, providing guaranteed and well specified overflow and underflow behavior that the user can configure.

`BITFIELD` is able to operate with multiple bit fields in the same command call. It takes a list of operations to perform, and returns an array of replies, where each array matches the corresponding operation in the list of arguments.

For example the following command increments a 5 bit signed integer at bit offset 100, and gets the value of the 4 bit unsigned integer at bit offset 0:

    > BITFIELD mykey INCRBY i5 100 1 GET u4 0
    1) (integer) 1
    2) (integer) 0

Note that:

1. Addressing with `GET` bits outside the current string length (including the case the key does not exist at all), results in the operation to be performed like the missing part all consists of bits set to 0.
2. Addressing with `SET` or `INCRBY` bits outside the current string length will enlarge the string, zero-padding it, as needed, for the minimal length needed, according to the most far bit touched.

title: Supported subcommands and integer encoding

role: compatibility

text:
The following is the list of supported commands.

* **GET** `<encoding>` `<offset>` -- Returns the specified bit field.
* **SET** `<encoding>` `<offset>` `<value>` -- Set the specified bit field and returns its old value.
* **INCRBY** `<encoding>` `<offset>` `<increment>` -- Increments or decrements (if a negative increment is given) the specified bit field and returns the new value.

There is another subcommand that only changes the behavior of successive
`INCRBY` and `SET` subcommands calls by setting the overflow behavior:

* **OVERFLOW** `[WRAP|SAT|FAIL]`

Where an integer encoding is expected, it can be composed by prefixing with `i` for signed integers and `u` for unsigned integers with the number of bits of our integer encoding. So for example `u8` is an unsigned integer of 8 bits and `i16` is a
signed integer of 16 bits.

The supported encodings are up to 64 bits for signed integers, and up to 63 bits for
unsigned integers. This limitation with unsigned integers is due to the fact
that currently the Redis protocol is unable to return 64 bit unsigned integers
as replies.

title: Bits and positional offsets

text:
There are two ways in order to specify offsets in the bitfield command.
If a number without any prefix is specified, it is used just as a zero based
bit offset inside the string.

However if the offset is prefixed with a `#` character, the specified offset
is multiplied by the integer encoding's width, so for example:

    BITFIELD mystring SET i8 #0 100 SET i8 #1 200

Will set the first i8 integer at offset 0 and the second at offset 8.
This way you don't have to do the math yourself inside your client if what
you want is a plain array of integers of a given size.

title: Overflow control

text:
Using the `OVERFLOW` command the user is able to fine-tune the behavior of
the increment or decrement overflow (or underflow) by specifying one of
the following behaviors:

* **WRAP**: wrap around, both with signed and unsigned integers. In the case of unsigned integers, wrapping is like performing the operation modulo the maximum value the integer can contain (the C standard behavior). With signed integers instead wrapping means that overflows restart towards the most negative value and underflows towards the most positive ones, so for example if an `i8` integer is set to the value 127, incrementing it by 1 will yield `-128`.
* **SAT**: uses saturation arithmetic, that is, on underflows the value is set to the minimum integer value, and on overflows to the maximum integer value. For example incrementing an `i8` integer starting from value 120 with an increment of 10, will result into the value 127, and further increments will always keep the value at 127. The same happens on underflows, but towards the value is blocked at the most negative value.
* **FAIL**: in this mode no operation is performed on overflows or underflows detected. The corresponding return value is set to NULL to signal the condition to the caller.

Note that each `OVERFLOW` statement only affects the `INCRBY` and `SET`
commands that follow it in the list of subcommands, up to the next `OVERFLOW`
statement.

By default, **WRAP** is used if not otherwise specified.

    > BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1
    1) (integer) 1
    2) (integer) 1
    > BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1
    1) (integer) 2
    2) (integer) 2
    > BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1
    1) (integer) 3
    2) (integer) 3
    > BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1
    1) (integer) 0
    2) (integer) 3

The following is an example of `OVERFLOW FAIL` returning NULL.

    > BITFIELD mykey OVERFLOW FAIL incrby u2 102 1
    1) (nil)

title: Motivations

text:
The motivation for this command is that the ability to store many small integers
as a single large bitmap (or segmented over a few keys to avoid having huge keys) is extremely memory efficient, and opens new use cases for Redis to be applied, especially in the field of real time analytics. This use cases are supported by the ability to specify the overflow in a controlled way.

Fun fact: Reddit's 2017 April fools' project [r/place](https://reddit.com/r/place) was [built using the Redis BITFIELD command](https://redditblog.com/2017/04/13/how-we-built-rplace/) in order to take an in-memory representation of the collaborative canvas.

title: Performance considerations

text: Usually `BITFIELD` is a fast command, however note that addressing far bits of currently short strings will trigger an allocation that may be more costly than executing the command on bits already existing.

title: Orders of bits

text:
The representation used by `BITFIELD` considers the bitmap as having the
bit number 0 to be the most significant bit of the first byte, and so forth, so
for example setting a 5 bits unsigned integer to value 23 at offset 7 into a
bitmap previously set to all zeroes, will produce the following representation:

    +--------+--------+
    |00000001|01110000|
    +--------+--------+

When offsets and integer sizes are aligned to bytes boundaries, this is the
same as big endian, however when such alignment does not exist, its important
to also understand how the bits inside a byte are ordered.

title: Return information

text:
**RESP2:**

One of the following:
* [Array reply](../../develop/reference/protocol-spec#arrays): each entry being the corresponding result of the sub-command given at the same position.
* [Nil reply](../../develop/reference/protocol-spec#bulk-strings): if OVERFLOW FAIL was given and overflows or underflows are detected.

**RESP3:**

One of the following:
* [Array reply](../../develop/reference/protocol-spec#arrays): each entry being the corresponding result of the sub-command given at the same position.
* [Null reply](../../develop/reference/protocol-spec#nulls): if OVERFLOW FAIL was given and overflows or underflows are detected.


title: BITFIELD_RO

summary: Performs arbitrary read-only bitfield integer operations on strings.

title: Overview

text:
Read-only variant of the [`BITFIELD`]() command.
It is like the original [`BITFIELD`]() but only accepts `GET` subcommand and can safely be used in read-only replicas.

Since the original [`BITFIELD`]() has `SET` and `INCRBY` options it is technically flagged as a writing command in the Redis command table.
For this reason read-only replicas in a Redis Cluster will redirect it to the master instance even if the connection is in read-only mode (see the [`READONLY`]() command of Redis Cluster).

Since Redis 6.2, the `BITFIELD_RO` variant was introduced in order to allow [`BITFIELD`]() behavior in read-only replicas without breaking compatibility on command flags.

See original [`BITFIELD`]() for more details.

title: Examples

text: [code example]

title: Return information

text:
**RESP2:**

[Array reply](../../develop/reference/protocol-spec#arrays): each entry being the corresponding result of the sub-command given at the same position.

**RESP3:**

[Array reply](../../develop/reference/protocol-spec#arrays): each entry being the corresponding result of the sub-command given at the same position.

code: BITFIELD_RO hello GET i8 16


title: BITOP

summary: Performs bitwise operations on multiple strings, and stores the result.

title: Overview

text:
This command's behavior varies in clustered Redis environments. See the [multi-key operations]() page for more information.

Perform a bitwise operation between multiple keys (containing string values) and
store the result in the destination key.

The `BITOP` command supports eight bitwise operations: `AND`, `OR`, `XOR`,
`NOT`, `DIFF`, `DIFF1`, `ANDOR`, and `ONE`. The valid forms to call the command are:

* `BITOP AND destkey srckey1 srckey2 srckey3 ... srckeyN`

    A bit in `destkey` is set only if it is set in all source bitmaps.
* `BITOP OR  destkey srckey1 srckey2 srckey3 ... srckeyN`

    A bit in `destkey` is set only if it is set in at least one source bitmap.
* `BITOP XOR destkey srckey1 srckey2 srckey3 ... srckeyN`

    Mostly used with two source bitmaps, a bit in `destkey` is set only if its value differs between the two source bitmaps.
* `BITOP NOT destkey srckey`

    `NOT` is a unary operator and only supports a single source bitmap; set the bit to the inverse of its value in the source bitmap.
* `BITOP DIFF destkey X [Y1 Y2 ...]` [1](#list-note-1)

    A bit in `destkey` is set if it is set in `X`, but not in any of `Y1, Y2, ...` .
* `BITOP DIFF1 destkey X [Y1 Y2 ...]` [1](#list-note-1)

    A bit in `destkey` is set if it is set in one or more of `Y1, Y2, ...`, but not in `X`.
* `BITOP ANDOR destkey X [Y1 Y2 ...]` [1](#list-note-1)

    A bit in `destkey` is set if it is set in `X` and also in one or more of `Y1, Y2, ...`.
* `BITOP ONE destkey X1 [X2 X3 ...]` [1](#list-note-1)

    A bit in `destkey` is set if it is set in exactly one of `X1, X2, ...`.

The result of each operation is always stored at `destkey`.

1.  Added in Redis 8.2.

title: Handling of strings with different lengths

text:
When an operation is performed between strings having different lengths, all the
strings shorter than the longest string in the set are treated as if they were
zero-padded up to the length of the longest string.

The same holds true for non-existent keys, that are considered as a stream of
zero bytes up to the length of the longest string.

title: Examples

text:
1. Basic usage example using the `AND` operator:

BITFIELD key1 SET i8 #0 255
BITFIELD key2 SET i8 #0 85
BITOP AND dest key1 key2
BITFIELD dest GET i8 #0

2. Suppose you want to expose people to a book-related ad. The target audience is people who love to read books and are interested in fantasy, adventure, or science fiction. Assume you have the following bitmaps:

* `LRB` - people who love to read books.
* `B:F` - people interested in fantasy.
* `B:A` - people interested in adventure.
* `B:SF` - people interested in science fiction.

To create a bitmap representing the target audience, use the following command:

[code example]

title: Pattern: real time metrics using bitmaps

text:
`BITOP` is a good complement to the pattern documented in the [`BITCOUNT`]() command
documentation.
Different bitmaps can be combined in order to obtain a target bitmap where
the population counting operation is performed.

See the article called "[Fast easy realtime metrics using Redis
bitmaps][hbgc212fermurb]" for an interesting use cases.

[hbgc212fermurb]: http://blog.getspool.com/2011/11/29/fast-easy-realtime-metrics-using-redis-bitmaps

title: Performance considerations

text:
`BITOP` is a potentially slow command as it runs in O(N) time.
Care should be taken when running it against long input strings.

For real-time metrics and statistics involving large inputs a good approach is
to use a replica (with replica-read-only option enabled) where the bit-wise
operations are performed to avoid blocking the master instance.

title: Return information

text:
**RESP2:**

[Integer reply](../../develop/reference/protocol-spec#integers): the size of the string stored in the destination key is equal to the size of the longest input string.

**RESP3:**

[Integer reply](../../develop/reference/protocol-spec#integers): the size of the string stored in the destination key is equal to the size of the longest input string.

code: BITOP ANDOR TA LRB B:F B:A B:SF


title: BITPOS

summary: Finds the first set (1) or clear (0) bit in a string.

title: Overview

text:
Return the position of the first bit set to 1 or 0 in a string.

The position is returned, thinking of the string as an array of bits from left to
right, where the first byte's most significant bit is at position 0, the second
byte's most significant bit is at position 8, and so forth.

The same bit position convention is followed by [`GETBIT`]() and [`SETBIT`]().

By default, all the bytes contained in the string are examined.
It is possible to look for bits only in a specified interval passing the additional arguments _start_ and _end_ (it is possible to just pass _start_, the operation will assume that the end is the last byte of the string. However there are semantic differences as explained later).
By default, the range is interpreted as a range of bytes and not a range of bits, so `start=0` and `end=2` means to look at the first three bytes.

You can use the optional `BIT` modifier to specify that the range should be interpreted as a range of bits.
So `start=0` and `end=2` means to look at the first three bits.

Note that bit positions are returned always as absolute values starting from bit zero even when _start_ and _end_ are used to specify a range.

Like for the [`GETRANGE`]() command start and end can contain negative values in
order to index bytes starting from the end of the string, where -1 is the last
byte, -2 is the penultimate, and so forth. When `BIT` is specified, -1 is the last
bit, -2 is the penultimate, and so forth.

Non-existent keys are treated as empty strings.

title: Examples

text: [code example]

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ✅ Standard
<nobr>✅ Active-Active</nobr> | ✅ Standard
<nobr>✅ Active-Active</nobr> |  |

title: Return information

text:
**RESP2:**

One of the following:
* [Integer reply](../../develop/reference/protocol-spec#integers): the position of the first bit set to 1 or 0 according to the request
* [Integer reply](../../develop/reference/protocol-spec#integers): `-1`. In case the `bit` argument is 1 and the string is empty or composed of just zero bytes
If we look for set bits (the bit argument is 1) and the string is empty or composed of just zero bytes, -1 is returned.
If we look for clear bits (the bit argument is 0) and the string only contains bits set to 1, the function returns the first bit not part of the string on the right. So if the string is three bytes set to the value `0xff` the command `BITPOS key 0` will return 24, since up to bit 23 all the bits are 1.
The function considers the right of the string as padded with zeros if you look for clear bits and specify no range or the _start_ argument **only**.
However, this behavior changes if you are looking for clear bits and specify a range with both _start_ and _end_.
If a clear bit isn't found in the specified range, the function returns -1 as the user specified a clear range and there are no 0 bits in that range.

**RESP3:**

One of the following:
* [Integer reply](../../develop/reference/protocol-spec#integers): the position of the first bit set to 1 or 0 according to the request
* [Integer reply](../../develop/reference/protocol-spec#integers): `-1`. In case the `bit` argument is 1 and the string is empty or composed of just zero bytes
If we look for set bits (the bit argument is 1) and the string is empty or composed of just zero bytes, -1 is returned.
If we look for clear bits (the bit argument is 0) and the string only contains bits set to 1, the function returns the first bit not part of the string on the right. So if the string is three bytes set to the value `0xff` the command `BITPOS key 0` will return 24, since up to bit 23 all the bits are 1.
The function considers the right of the string as padded with zeros if you look for clear bits and specify no range or the _start_ argument **only**.
However, this behavior changes if you are looking for clear bits and specify a range with both _start_ and _end_.
If a clear bit isn't found in the specified range, the function returns -1 as the user specified a clear range and there are no 0 bits in that range.

code:
redis> SET mykey "\xff\xf0\x00"
OK
redis> BITPOS mykey 0
(integer) 12
redis> SET mykey "\x00\xff\xf0"
OK
redis> BITPOS mykey 1 0
(integer) 8
redis> BITPOS mykey 1 2
(integer) 16
redis> BITPOS mykey 1 2 -1 BYTE
(integer) 16
redis> BITPOS mykey 1 7 15 BIT
(integer) 8
redis> set mykey "\x00\x00\x00"
OK
redis> BITPOS mykey 1
(integer) -1
redis> BITPOS mykey 1 7 -3 BIT
(integer) -1


title: BLMOVE

summary: Pops an element from a list, pushes it to another list and returns it. Blocks until an element is available otherwise. Deletes the list if the last element was moved.

title: Overview

text:
This command's behavior varies in clustered Redis environments. See the [multi-key operations]() page for more information.

`BLMOVE` is the blocking variant of [`LMOVE`]().
When `source` contains elements, this command behaves exactly like [`LMOVE`]().
When used inside a [`MULTI`]()/[`EXEC`]() block or a Lua script, this command behaves exactly like [`LMOVE`]().
When `source` is empty, Redis will block the connection until another client
pushes to it or until `timeout` (a double value specifying the maximum number of seconds to block) is reached.
A `timeout` of zero can be used to block indefinitely.

This command comes in place of the now deprecated [`BRPOPLPUSH`](). Doing
`BLMOVE RIGHT LEFT` is equivalent.

See [`LMOVE`]() for more information.

title: Pattern: Reliable queue

text: Please see the pattern description in the [`LMOVE`]() documentation.

title: Pattern: Circular list

title: Return information

text:
**RESP2:**

One of the following:
* [Bulk string reply](../../develop/reference/protocol-spec#bulk-strings): the element being popped from the _source_ and pushed to the _destination_.
* [Nil reply](../../develop/reference/protocol-spec#bulk-strings): the operation timed-out

**RESP3:**

One of the following:
* [Bulk string reply](../../develop/reference/protocol-spec#bulk-strings): the element being popped from the _source_ and pushed to the _destination_.
* [Null reply](../../develop/reference/protocol-spec#nulls): the operation timed-out


title: BLMPOP

summary: Pops the first element from one of multiple lists. Blocks until an element is available otherwise. Deletes the list if the last element was popped.

title: Overview

text:
This command's behavior varies in clustered Redis environments. See the [multi-key operations]() page for more information.

`BLMPOP` is the blocking variant of [`LMPOP`]().

When any of the lists contains elements, this command behaves exactly like [`LMPOP`]().
When used inside a [`MULTI`]()/[`EXEC`]() block or a Lua script, this command behaves exactly like [`LMPOP`]().
When all lists are empty, Redis will block the connection until another client pushes to it or until the `timeout` (a double value specifying the maximum number of seconds to block) elapses.
A `timeout` of zero can be used to block indefinitely.

See [`LMPOP`]() for more information.

title: Return information

text:
**RESP2:**

One of the following:
* [Nil reply](../../develop/reference/protocol-spec#bulk-strings): when no element could be popped and the _timeout_ is reached.
* [Array reply](../../develop/reference/protocol-spec#arrays): a two-element array with the first element being the name of the key from which elements were popped, and the second element being an array of the popped elements.

**RESP3:**

One of the following:
* [Null reply](../../develop/reference/protocol-spec#nulls): when no element could be popped and the _timeout_ is reached.
* [Array reply](../../develop/reference/protocol-spec#arrays): a two-element array with the first element being the name of the key from which elements were popped, and the second element being an array of the popped elements.


title: BLPOP

summary: Removes and returns the first element in a list. Blocks until an element is available otherwise. Deletes the list if the last element was popped.

title: Overview

text:
This command's behavior varies in clustered Redis environments. See the [multi-key operations]() page for more information.

`BLPOP` is a blocking list pop primitive.
It is the blocking version of [`LPOP`]() because it blocks the connection when there
are no elements to pop from any of the given lists.
An element is popped from the head of the first list that is non-empty, with the
given keys being checked in the order that they are given.

title: Non-blocking behavior

text:
When `BLPOP` is called, if at least one of the specified keys contains a
non-empty list, an element is popped from the head of the list and returned to
the caller together with the `key` it was popped from.

Keys are checked in the order that they are given.
Let's say that the key `list1` doesn't exist and `list2` and `list3` hold
non-empty lists.
Consider the following command:

[code example]

`BLPOP` guarantees to return an element from the list stored at `list2` (since
it is the first non empty list when checking `list1`, `list2` and `list3` in
that order).

title: Blocking behavior

text:
If none of the specified keys exist, `BLPOP` blocks the connection until another
client performs an [`LPUSH`]() or [`RPUSH`]() operation against one of the keys.

Once new data is present on one of the lists, the client returns with the name
of the key unblocking it and the popped value.

When `BLPOP` causes a client to block and a non-zero timeout is specified,
the client will unblock returning a `nil` multi-bulk value when the specified
timeout has expired without a push operation against at least one of the
specified keys.

**The timeout argument is interpreted as a double value specifying the maximum number of seconds to block**. A timeout of zero can be used to block indefinitely.

title: What key is served first? What client? What element? Priority ordering details.

text:
* If the client tries to block for multiple keys, but at least one key contains elements, the returned key/element pair is the first key from left to right that has one or more elements. In this case, the client is not blocked. For example, `BLPOP key1 key2 key3 key4 0`, assuming that both `key2` and `key4` are non-empty, will always return an element from `key2`.

* If multiple clients are blocked for the same key, the first client to be served is the one that has been waiting the longest (the first that blocked for the key). Once a client is unblocked it does not retain any priority; when it blocks again with another `BLPOP` call, it will be served according to its new position in the queue.

* When a client is blocking for multiple keys and multiple keys become non-empty as a result of the same command, transaction, or Lua script, the client is served according to the **order of keys in its `BLPOP` call**, not the order of the write operations. After the writes occur, Redis reprocesses the blocking command for the client and pops from the **first non-empty key** in the key list.
For example, a client blocked on `BLPOP key1 key2 0` will pop from `key1` if both `key1` and `key2` receive elements during the same `MULTI`/`EXEC` transaction, because `key1` appears first.

Internally, when a write makes progress possible for a blocked client, Redis marks that client as unblocked (adding it to an internal queue). No reply is sent immediately. Before the server goes idle (in the `beforeSleep()` phase), Redis rechecks the blocking command and serves the client based on the first non-empty key in its provided key list.

#### Example

**Client A**

[code example]

**Client B**

[code example]

Although `key2` is pushed first inside the transaction, Redis reprocesses the blocking command for Client A after the transaction completes.
At that time both lists are non-empty, and `BLPOP` pops from the first non-empty key in its argument list (`key1`):

[code example]

To make Redis pop from `key2` instead, reverse the order of the keys in the blocking call:

[code example]

title: Behavior of `BLPOP` when multiple elements are pushed inside a list.

text:
There are times when a list can receive multiple elements in the context of the same conceptual command:

* Variadic push operations such as `LPUSH mylist a b c`.
* After an [`EXEC`]() of a [`MULTI`]() block with multiple push operations against the same list.
* Executing a Lua Script with Redis 2.6 or newer.

When multiple elements are pushed inside a list where there are clients blocking, the behavior is different for Redis 2.4 and Redis 2.6 or newer.

For Redis 2.6 what happens is that the command performing multiple pushes is executed, and *only after* the execution of the command the blocked clients are served. Consider this sequence of commands.

    Client A:   BLPOP foo 0
    Client B:   LPUSH foo a b c

If the above condition happens using a Redis 2.6 server or greater, Client **A** will be served with the `c` element, because after the [`LPUSH`]() command the list contains `c,b,a`, so taking an element from the left means to return `c`.

Instead Redis 2.4 works in a different way: clients are served *in the context* of the push operation, so as long as `LPUSH foo a b c` starts pushing the first element to the list, it will be delivered to the Client **A**, that will receive `a` (the first element pushed).

The behavior of Redis 2.4 creates a lot of problems when replicating or persisting data into the AOF file, so the much more generic and semantically simpler behavior was introduced into Redis 2.6 to prevent problems.

Note that for the same reason a Lua script or a `MULTI/EXEC` block may push elements into a list and afterward **delete the list**. In this case the blocked clients will not be served at all and will continue to be blocked as long as no data is present on the list after the execution of a single command, transaction, or script.

title: `BLPOP` inside a `MULTI` / `EXEC` transaction

text:
`BLPOP` can be used with pipelining (sending multiple commands and
reading the replies in batch), however this setup makes sense almost solely
when it is the last command of the pipeline.

Using `BLPOP` inside a [`MULTI`]() / [`EXEC`]() block does not make a lot of sense
as it would require blocking the entire server in order to execute the block
atomically, which in turn does not allow other clients to perform a push
operation. For this reason the behavior of `BLPOP` inside [`MULTI`]() / [`EXEC`]() when the list is empty is to return a `nil` multi-bulk reply, which is the same
thing that happens when the timeout is reached.

If you like science fiction, think of time flowing at infinite speed inside a
[`MULTI`]() / [`EXEC`]() block...

title: Examples

text: [code example]

title: Reliable queues

text:
When `BLPOP` returns an element to the client, it also removes the element from the list. This means that the element only exists in the context of the client: if the client crashes while processing the returned element, it is lost forever.

This can be a problem with some application where we want a more reliable messaging system. When this is the case, please check the [`BRPOPLPUSH`]() command, that is a variant of `BLPOP` that adds the returned element to a target list before returning it to the client.

title: Pattern: Event notification

text:
Using blocking list operations it is possible to mount different blocking
primitives.
For instance for some application you may need to block waiting for elements
into a Redis Set, so that as far as a new element is added to the Set, it is
possible to retrieve it without resort to polling.
This would require a blocking version of [`SPOP`]() that is not available, but using
blocking list operations we can easily accomplish this task.

The consumer will do:

[code example]

While in the producer side we'll use simply:

[code example]

title: Return information

text:
**RESP2:**

One of the following:
* [Nil reply](../../develop/reference/protocol-spec#bulk-strings): no element could be popped and the timeout expired
* [Array reply](../../develop/reference/protocol-spec#arrays): the key from which the element was popped and the value of the popped element.

**RESP3:**

One of the following:
* [Null reply](../../develop/reference/protocol-spec#nulls): no element could be popped and the timeout expired
* [Array reply](../../develop/reference/protocol-spec#arrays): the key from which the element was popped and the value of the popped element.

code: BLPOP list1 list2 list3 0

section_id: non-blocking-behavior

code: BLPOP key1 key2 0

code:
MULTI
RPUSH key2 1 2 3 4
RPUSH key1 5 6 7
EXEC

code: BLPOP key2 key1 0

code:
redis> DEL list1 list2
(integer) 0
redis> RPUSH list1 a b c
(integer) 3
redis> BLPOP list1 list2 0
1) "list1"
2) "a"

code:
LOOP forever
    WHILE SPOP(key) returns elements
        ... process elements ...
    END
    BRPOP helper_key
END

section_id: pattern-event-notification

code:
MULTI
SADD key element
LPUSH helper_key x
EXEC


title: BRPOP

summary: Removes and returns the last element in a list. Blocks until an element is available otherwise. Deletes the list if the last element was popped.

title: Overview

text:
This command's behavior varies in clustered Redis environments. See the [multi-key operations]() page for more information.

`BRPOP` is a blocking list pop primitive.
It is the blocking version of [`RPOP`]() because it blocks the connection when there
are no elements to pop from any of the given lists.
An element is popped from the tail of the first list that is non-empty, with the
given keys being checked in the order that they are given.

See the [BLPOP documentation][cb] for the exact semantics, since `BRPOP` is
identical to [`BLPOP`]() with the only difference being that it pops elements from
the tail of a list instead of popping from the head.

[cb]: /commands/blpop

title: Examples

text: [code example]

title: Return information

text:
**RESP2:**

One of the following:
* [Nil reply](../../develop/reference/protocol-spec#bulk-strings): no element could be popped and the timeout expired.
* [Array reply](../../develop/reference/protocol-spec#arrays): the key from which the element was popped and the value of the popped element

**RESP3:**

One of the following:
* [Null reply](../../develop/reference/protocol-spec#nulls): no element could be popped and the timeout expired.
* [Array reply](../../develop/reference/protocol-spec#arrays): the key from which the element was popped and the value of the popped element

code:
redis> DEL list1 list2
(integer) 0
redis> RPUSH list1 a b c
(integer) 3
redis> BRPOP list1 list2 0
1) "list1"
2) "c"


title: BRPOPLPUSH

summary: Pops an element from a list, pushes it to another list and returns it. Block until an element is available otherwise. Deletes the list if the last element was popped.

title: Overview

text:
This command's behavior varies in clustered Redis environments. See the [multi-key operations]() page for more information.

`BRPOPLPUSH` is the blocking variant of [`RPOPLPUSH`]().
When `source` contains elements, this command behaves exactly like [`RPOPLPUSH`]().
When used inside a [`MULTI`]()/[`EXEC`]() block or a Lua script, this command behaves exactly like [`RPOPLPUSH`]().
When `source` is empty, Redis will block the connection until another client
pushes to it or until `timeout` is reached.
A `timeout` of zero can be used to block indefinitely.

See [`RPOPLPUSH`]() for more information.

title: Pattern: Reliable queue

text: Please see the pattern description in the [`RPOPLPUSH`]() documentation.

title: Pattern: Circular list

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ✅ Standard
<nobr>✅ Active-Active</nobr> | ✅ Standard
<nobr>✅ Active-Active</nobr> | Deprecated as of Redis v6.2.0. |

title: Return information

text:
**RESP2:**

One of the following:
* [Bulk string reply](../../develop/reference/protocol-spec#bulk-strings): the element being popped from _source_ and pushed to _destination_.
* [Nil reply](../../develop/reference/protocol-spec#bulk-strings): the timeout is reached.

**RESP3:**

One of the following:
* [Bulk string reply](../../develop/reference/protocol-spec#bulk-strings): the element being popped from _source_ and pushed to _destination_.
* [Null reply](../../develop/reference/protocol-spec#nulls): the timeout is reached.