Redis is an in-memory database that stores named keys associated with values such as strings, hashes, lists, sets, and ordered collections. Often described as a data structure server, it lets applications manipulate these values through server-side commands rather than retrieve and rewrite entire objects. Its data model supports uses ranging from caching and counters to queues and event processing. (redis.io)
Redis combines memory-based data access with optional disk persistence, replication, and distributed deployment. These features allow it to serve either as a temporary store alongside another database or as a persistent database, with different durability and availability properties depending on configuration. Its architecture illustrates important trade-offs in distributed computing, including the relationships between latency, memory capacity, write durability, and failover. (redis.io)
Created by Salvatore Sanfilippo in 2009, Redis subsequently developed a broader set of storage and query capabilities. Redis 8, released on May 1, 2025, integrated capabilities previously distributed through separate modules, including JSON, time series, probabilistic structures, and search. The project’s history also includes changes in maintenance, licensing, and the emergence of independently developed forks. (redis.io)
Origins, development, and project stewardship
Salvatore Sanfilippo, known online as antirez, created Redis in 2009 to address data-access and scaling problems at his startup. The immediate application was LLOOGG, a web-traffic monitoring service whose workload had outgrown its existing database arrangement. Redis placed working data in memory while providing disk persistence, and exposed operations on data structures rather than requiring every operation to be expressed through relational queries. In a June 19, 2009, account, Sanfilippo reported that LLOOGG had switched entirely to Redis and that its MySQL server had been turned off. Redis thus began as infrastructure for a specific application before developing into a separately maintained open-source software project. (redis.io)
The software project preceded the commercial company that later supported its development. That company, then called Redis Labs, was founded in 2011; it was not the startup at which Redis originated. On July 15, 2015, Redis Labs announced that Sanfilippo was joining as lead of open-source Redis development, continuing a role previously supported at VMware and Pivotal. The arrangement brought the project’s creator into the company without marking either the creation of Redis or the beginning of his technical leadership. Corporate sponsorship and project maintenance therefore had distinct timelines, even as the company increasingly supplied engineering resources. (redis.io)
On June 30, 2020, after approximately eleven years as principal maintainer, Sanfilippo announced that he was stepping back from day-to-day maintenance. Yossi Gottlieb and Oran Agra succeeded him as project leads and introduced a lightweight governance model organized around a small core team. Previously, Sanfilippo had retained the final decision on accepted features, bug fixes, and design trade-offs; the new model distributed responsibility among developers selected for demonstrated knowledge, contributions, and commitment. Itamar Haber was announced as the first additional member. The transition covered practical responsibilities such as reviewing contributions, fixing bugs, and preparing releases; the contemporaneous announcement also specified a technical advisory role for Sanfilippo at the company. (redis.io)
Redis’s expansion beyond its core server initially relied on separately supplied modules. On March 23, 2022, Redis introduced Redis Stack to package several of these extensions together and simplify installation, documentation, and client support. Its initial server distribution combined Redis with RediSearch, RedisJSON, RedisGraph, RedisTimeSeries, and RedisBloom, adding search, document, graph, time-series, and probabilistic capabilities. The broader suite included RedisInsight for visualization and debugging, alongside client libraries and object-mapping libraries. At launch, Redis Stack was explicitly presented as an additional distribution rather than a replacement for the core Redis server. (redis.io)
Redis 8 reached general availability on May 1, 2025, combining the community server and Redis Stack offerings into a single Redis Open Source distribution. Search and query functionality, JSON documents, time-series storage, and five probabilistic structures were included in the package, reducing the need to select and match separate module versions. The release also introduced vector sets in beta, developed by Sanfilippo, alongside the existing vector-search capabilities of the Redis Query Engine. This integration changed how capabilities were delivered: features previously associated with an extended Stack installation became part of the Redis 8 distribution. (redis.io)
Keyspace and fundamental data types
Redis organizes each database as a keyspace in which a unique key identifies a typed value. The value may be a single string or a collection represented by a native data structure. Keys are binary-safe byte sequences: they need not be valid text and may contain whitespace, punctuation, or non-text bytes. Names such as user:42 and counter:visits use a conventional colon separator; the separator does not create a directory hierarchy or an enforced namespace. Applications assign these names and avoid collisions within the same database. TYPE user:42 identifies the stored value’s type, while commands such as EXISTS and DEL operate on keys irrespective of that type. (redis.io)
A string value is also binary-safe and can hold text, serialized application data, or arbitrary bytes; its default maximum size is 512 MB. SET counter:visits 10 stores the string representation of ten, and GET counter:visits retrieves it. Numeric commands interpret suitable string contents as numbers: INCR counter:visits changes this example to eleven, while INCRBY counter:visits 5 changes it to sixteen. Each increment is atomic, avoiding an application-side read–modify–write sequence in which concurrent clients could overwrite one another’s updates. An increment on a missing key starts from zero. Counters are therefore a use of the string type, not a separate fundamental data type. (redis.io)
A hash stores field–value pairs beneath one top-level key. For example, HSET user:42 name Ada visits 10 creates or updates two fields in the hash identified by user:42. Here, name and visits are fields, not independent keys in the database keyspace. HGET user:42 name retrieves only the name, HMGET user:42 name visits retrieves the two selected values, and HGETALL user:42 retrieves every field–value pair. HINCRBY user:42 visits 1 changes only the numerical field to eleven. These commands let clients access and modify individual attributes without fetching, deserializing, and replacing an entire application object. Hash field values are strings rather than recursively nested Redis collections. (redis.io)
Lists maintain a positional sequence of strings and permit repeated values. Insertions at the head and tail have different effects: LPUSH prepends elements, whereas RPUSH appends them; LPOP and RPOP remove elements from the corresponding ends. Thus, appending a, b, and a to an initially absent list preserves all three entries in that order. LRANGE retrieves a positional interval. An unordered set instead stores each distinct string only once: adding an existing member does not create a duplicate, and iteration does not promise insertion order. SISMEMBER tests membership, while intersection, union, and difference commands combine collections according to set semantics. (redis.io)
Sorted sets combine unique string members with numerical, floating-point scores. Order follows increasing score rather than insertion time; members with equal scores are ordered lexicographically. For example, ZADD scores 120 Ada 95 Ben places Ben before Ada in ascending order. Adding Ada again with a different score updates the existing member rather than introducing a duplicate. Commands support retrieval by rank or score interval, and ZRANGE scores 0 1 WITHSCORES returns the first two members together with their scores. The associated score determines ordering; it is not an arbitrary record containing additional fields. (redis.io)
Command cost depends on the operation, not merely on the type of its target. In Big O notation, Redis documents SISMEMBER as , independent of set cardinality, whereas SUNION is , with representing the total number of members across its input sets. Retrieving an entire hash with HGETALL is likewise in its field count. Sorted-set insertion takes per member, and a rank-range retrieval takes , where is the number of returned members. These distinctions in time complexity separate direct membership checks from commands that traverse collections, combine their contents, or construct large results. (redis.io)
Specialized structures, indexing, and search
Bitmaps and bitfields interpret Redis string values at bit-level granularity rather than introducing separate storage types. SETBIT and GETBIT address individual bits; BITCOUNT counts set bits, while BITOP combines strings through bitwise operations. A daily activity bitmap can therefore assign one bit to each user identifier and count active users without storing identifiers as set members. BITFIELD, introduced in Redis 3.2, packs signed or unsigned integers of specified widths into a string and supports atomic reads, assignments, and increments, with wrapping, saturation, or failure on overflow. Geospatial indexes instead associate named locations with longitude–latitude coordinates: GEOADD records points, and GEOSEARCH retrieves those within a specified radius or rectangular area. (redis.io)
HyperLogLog estimates cardinality—the number of distinct observed elements—without retaining an enumerable collection of those elements. Redis’s implementation uses up to approximately 12 KB for the estimator and has a standard error of 0.81%; this is a statistical error measure, not a guaranteed bound on every result. PFADD incorporates observations, PFCOUNT estimates their distinct count, and PFMERGE combines estimators. For example, daily visitor estimators can be merged to estimate distinct visitors across several days rather than incorrectly summing overlapping daily counts. Unlike an ordinary set, this structure cannot return the original members or answer exact membership queries. (redis.io)
The other probabilistic structures answer different questions. A Bloom filter tests membership with possible false positives: “possibly present” differs from the definite absence reported by a negative result. Cuckoo filters provide a related membership test using compact fingerprints and support deletion. Count-min sketches estimate item frequencies using counters shared through hashing; collisions can cause overcounting. Top-K tracks an approximate collection of the most frequent items, rather than an exact ranking of every item, while t-digest estimates quantiles, such as the 99th-percentile value of a latency distribution. These structures trade exact answers for compact representations; they are not interchangeable with exact set membership, counters, or sorted-set rankings. (redis.io)
JSON values preserve hierarchical objects and arrays rather than treating a document solely as an opaque serialized string. JSONPath expressions select nested elements for retrieval and modification; an application can update an individual property or array without retrieving and replacing the whole document. The time-series structure stores timestamp–numeric-value samples, with timestamps expressed in Unix milliseconds. TS.ADD records a measurement, and TS.RANGE retrieves measurements within a time interval, optionally aggregating them into time buckets—for example, computing minute-by-minute averages from sensor readings. Retention periods and compaction rules control the preservation of raw and downsampled measurements. (redis.io)
The Redis Query Engine provides indexed retrieval beyond lookup by key. FT.CREATE defines a secondary-index schema over hashes or JSON documents, including text, numerical, tag, geographic, and vector fields. Queries can combine full-text matching with field restrictions, such as a product category and price range. Vector fields support nearest-neighbor and distance-range searches, including metadata filtering; available distance measures include Euclidean distance and cosine distance. Indexes are maintained as documents change. JSON, time series, the five additional probabilistic structures, and the Query Engine—previously available through modules or Redis Stack—were packaged together in Redis 8, generally available on May 1, 2025; their presence should not be assumed in an unextended older server. (redis.io)
Vector sets are a distinct key-level data type, not another name for a Query Engine vector index. Developed by Salvatore Sanfilippo and introduced in beta in Redis 8.0, they associate element names directly with high-dimensional vectors. VADD inserts elements, and VSIM retrieves similar elements through a hierarchical navigable small-world graph. Query Engine vector search instead indexes vector fields within hash or JSON documents under an explicitly defined schema. The beta designation at introduction applied to vector sets and their potentially changing interface, not to all vector-search functionality in Redis. (redis.io)
Server architecture and memory management
Redis Open Source maintains its working dataset in main memory: ordinary reads and updates operate on memory-resident objects rather than fetching database pages from disk. Its event loop multiplexes client connections, handling network readiness without assigning a dedicated execution thread to every connection. Most core commands execute sequentially on the main thread, so a computationally expensive command can delay unrelated clients. This execution model does not mean that the entire server uses only one thread. Background threads perform selected tasks, including slow disk I/O; persistence can also involve child processes. Redis 6 introduced optional I/O threading for network reads, writes, and protocol parsing, and Redis 8 introduced a revised implementation controlled through io-threads. Parallel network processing does not, by itself, make ordinary command execution parallel. (redis.io)
A value’s externally visible data type is distinct from its internal encoding. Small aggregate data structures can use compact representations that avoid the allocation and pointer overhead of larger structures. In Redis 7.0, for example, the documented defaults permit a hash to use a listpack with up to 512 field–value pairs, provided individual fields and values do not exceed 64 bytes; sorted-set listpack defaults allow 128 members with a 64-byte value threshold. Listpacks store entries compactly, trading some CPU work for reduced memory consumption. Small collections can tolerate sequential searches, whereas larger ones benefit from structures such as hash tables. When an insertion exceeds the configured size or element-count threshold, Redis automatically converts the object to a more general encoding without changing its command interface. Raising these thresholds can save memory but increases the work required for searches and eventual conversion. (redis.io)
The maxmemory setting establishes the memory threshold used to trigger key eviction, not a hard ceiling on total process memory. Some replication and append-only-file buffers are excluded from eviction accounting, and a large operation can temporarily overshoot the threshold. maxmemory-policy selects the response: allkeys-lru approximates least-recently-used eviction, allkeys-lfu approximates least-frequently-used eviction, and allkeys-random selects victims randomly. Corresponding volatile-* policies restrict eligibility to keys with expiration metadata; volatile-ttl favors those with the shortest remaining lifetime. Under noeviction, Redis rejects commands requiring additional dataset memory rather than discarding existing keys, while reads remain available. (redis.io)
Redis avoids maintaining an exact global LRU ordering. Instead, it samples candidate keys and favors those with older access times; since Redis 3.0, a retained candidate pool improves selection. Increasing maxmemory-samples improves approximation at additional CPU cost. LFU, introduced in Redis 4.0, uses probabilistic access counters with decay, allowing previously popular but now inactive keys to become eviction candidates. (redis.io)
Expiration is independent of memory pressure. Commands such as EXPIRE attach time-to-live metadata to a key; Redis stores its deadline as an absolute Unix timestamp, with millisecond resolution since version 2.6. Expired keys are removed passively when accessed and actively through periodic checks, including keys that clients never request again. For example, EXPIRE session:42 1800 gives a session key a 30-minute lifetime even when memory remains plentiful. Conversely, an eviction policy may discard it before that deadline. PERSIST removes expiration metadata but does not protect the key from an allkeys-* eviction policy. Thus retaining temporary application state until a deadline and retaining it under memory pressure are separate properties; removing a timeout alone does not guarantee retention. (redis.io)
Client protocol, transactions, and programmability
Clients communicate through the Redis Serialization Protocol (RESP), normally over persistent TCP connections rather than opening a connection for each command. Requests are arrays of binary-safe bulk strings containing the command name and arguments. RESP2 replies comprise simple strings, errors, integers, bulk strings, and arrays, with null representations for missing values. RESP3 adds explicit nulls, booleans, doubles, big numbers, maps, sets, attributes, bulk errors, verbatim strings, and out-of-band push messages; clients can select it with HELLO 3. Client libraries translate these representations into language-level values and commonly manage reusable connections through pooling or multiplexing. The redis-cli tool supports both an interactive command prompt and individual commands supplied as terminal arguments. (redis.io)
Pipelining sends several commands without waiting for each preceding reply, then reads the responses in order. For example, four INCR counter requests can be transmitted together instead of requiring four successive request–response exchanges. Besides reducing network round-trip overhead, batching allows multiple requests or replies to share read() and write() system calls. The server must buffer unread replies, so very large pipelines increase memory consumption; Redis documentation illustrates bounded batches of 10,000 commands. A pipeline alone provides no transaction isolation or group atomicity: it changes communication scheduling, not the execution guarantees of the commands it contains. (redis.io)
Redis transactions use MULTI to begin queuing commands, EXEC to execute them sequentially without another client's commands intervening, and DISCARD to abandon the queue. EXEC returns an array containing each command's result. Thus, MULTI, INCR foo, INCR bar, and EXEC increment both counters as one isolated operation. This does not provide general rollback. Since version 2.6.5, errors detected while queuing, such as an unknown command or incorrect argument count, cause execution to be refused. An execution-time error, such as applying a list operation to a string, instead appears among the results; other queued commands still execute, and successful changes remain. (redis.io)
WATCH supplies optimistic concurrency control rather than reserving keys. A client can watch balance, read its value, calculate a replacement, and submit a transaction. If the watched key changes before EXEC, Redis aborts the transaction without executing its queued commands, allowing the application to retry with a fresh read. Changes include writes by other clients and server-side expiration or eviction; expiration began invalidating watched transactions in Redis 6.0.9. Watching must precede the read whose validity is being checked. EXEC, successful or otherwise, clears watched keys, as does DISCARD; UNWATCH clears them explicitly. (redis.io)
Server-side Lua scripts allow conditional read–compute–write logic without client-side round trips between its steps. Introduced in Redis 2.6, EVAL accepts script source, a key count, key names, and additional arguments; scripts access these through KEYS and ARGV. SCRIPT LOAD and EVALSHA permit subsequent invocation by a SHA-1 digest, but the script cache is not durable application-code storage: clients must handle missing scripts and reload them. Redis Functions, introduced in version 7.0, instead organize named functions into libraries loaded with FUNCTION LOAD and invoked with FCALL. Function libraries are database-managed artifacts included in persistence and replication. (redis.io)
Scripts and functions execute atomically relative to other clients, so long-running logic blocks ordinary command execution. Exceeding the configured execution-time threshold does not automatically terminate a script and undo its writes. Modules provide a different extension mechanism: dynamically loaded native libraries use Redis's C API to register commands and implement new data types, rather than merely composing existing commands in Lua. Module-defined types can supply callbacks for saving, loading, and append-only-file rewriting. The modules API also supports asynchronous operations that block a requesting client without blocking the entire server. (redis.io)
Persistence, recovery, and durability
Redis Database (RDB) persistence stores a compact, binary, point-in-time image of the dataset, usually in dump.rdb. Recovery restores that image rather than replaying its preceding command history. Snapshot rules combine elapsed time and changes: save 60 1000, for example, requests a snapshot after 60 seconds when at least 1,000 changes have occurred. Writes not represented in the latest completed snapshot can be lost after a crash. RDB therefore provides discrete recovery points, not continuous durability. Its compact, single-file representation also supports transferring and retaining historical dataset copies. (redis.io)
Background snapshotting uses BGSAVE and the operating system’s fork() mechanism. The child writes a temporary RDB file and replaces the previous snapshot only after completion, while the parent continues processing requests. With copy-on-write, parent and child initially share memory pages; subsequent modifications require private copies, increasing memory consumption according to the pages changed during the save. Forking itself can pause request handling, so “background” does not mean latency-free. By contrast, SAVE serializes the dataset synchronously and blocks other clients throughout the operation. (redis.io)
Append-only-file (AOF) persistence records dataset-changing operations and replays the persisted sequence during startup. Its synchronization policy determines the gap between accepting writes and forcing their log records to storage. appendfsync always synchronizes each appended batch before replies are sent; multiple commands can share one synchronization. The default, appendfsync everysec, normally synchronizes once per second using a background thread, accepting approximately one second of potential write loss in exchange for lower synchronization overhead. appendfsync no leaves flushing to the operating system, making the loss window dependent on its behavior. Writing into operating-system buffers is therefore distinct from completing fsync. (redis.io)
AOF rewriting limits growth by replacing accumulated history with a representation sufficient to reconstruct the current dataset. Repeatedly updating one counter need not preserve every intermediate value. BGREWRITEAOF requests background rewriting; automatic triggering has been available since Redis 2.4. A failed rewrite leaves the existing AOF intact, and a rewrite requested during background snapshotting is scheduled until that snapshot finishes. Since Redis 7.0, AOF persistence uses a base file, incremental files, and a manifest identifying the active set. During rewriting, new writes enter a new incremental file while the child generates the replacement base; an atomic manifest replacement activates the resulting set. (redis.io)
RDB and AOF can operate together. Under normal startup rules, Redis selects AOF when both are enabled because it is expected to contain the more complete recovery history; it does not merge two independently recovered datasets. Persistence can also be disabled, as in deployments storing disposable cached values, leaving no current disk-backed recovery state. (redis.io)
Recoverable persistence files are not equivalent to separately retained backups: files on the same failed storage device do not protect against its loss, and replacing the current snapshot does not preserve earlier recovery points. For multi-part AOF, a backup requires a coherent manifest and its referenced base and incremental files. Copying these during a rewrite can produce an invalid set because the active file inventory changes. Redis documentation therefore describes coordinating file copying with rewrite activity; retaining copies separately also preserves recovery points beyond the instance’s current persistence files. (redis.io)
Replication, Sentinel, and Redis Cluster
Redis uses asynchronous primary–replica replication: a primary streams dataset changes to replicas without normally waiting for their acknowledgment before replying to clients. Replica reads can therefore return stale values. A replication ID identifies a dataset history, while a byte offset identifies progress through its replication stream. After a disconnection, a replica issues PSYNC with its previous ID and offset. If the primary recognizes that history and retains the missing bytes in its in-memory replication backlog, partial resynchronization transfers only those bytes. Otherwise, full synchronization transfers an RDB snapshot followed by changes buffered during snapshot generation. Diskless replication, introduced in Redis 2.8.18, can stream the snapshot directly from a child process without an intermediate disk file. (redis.io)
Redis Sentinel supplies monitoring, failure detection, automatic failover, and primary discovery for non-clustered deployments. A Sentinel marks an unresponsive instance subjectively down; agreement by the configured quorum establishes that a primary is objectively down. Authorizing failover additionally requires election support from a majority of Sentinels, or the quorum if it is larger. Thus, with five Sentinels and quorum two, two can establish failure, but at least three must authorize the failover leader. That leader promotes a replica and reconfigures the remaining replicas to follow it. Sentinel manages availability, not data partitioning. (redis.io) Sentinel-aware clients resolve a named primary through SENTINEL get-master-addr-by-name and repeat discovery when reconnecting, rather than treating its address as permanent. (redis.io)
Redis Cluster combines partitioning with per-primary replication and its own failover mechanism. It distributes keys among 16,384 hash slots, normally calculated as . Primaries own subsets of slots; replicas copy their respective primaries rather than the entire cluster. Hash tags alter placement by hashing a designated nonempty substring within braces: user:{123}:profile and user:{123}:account, for example, share a slot. Multi-key commands, transactions, and Lua scripts generally require all involved keys to occupy the same slot; placement on the same node alone is insufficient. (redis.io) Resharding transfers slots and their keys between primaries. A MOVED reply directs clients to a slot’s current owner and permits updating their routing map. During migration, ASK instead redirects only the current request: the client sends ASKING to the destination before retrying, without permanently changing its slot mapping. (redis.io)
An acknowledged write can disappear if a primary fails before its replication stream reaches the replica subsequently promoted. Network partitions create another loss window: an isolated primary may initially accept writes while the majority side promotes its replica. Those isolated writes can be discarded when the old primary rejoins. In Redis Cluster, a primary unable to contact a majority of primaries stops accepting writes after the configured node timeout. The majority side can recover service through elections if suitable replicas are available for failed primaries; a majority of nodes alone does not supply missing data. (redis.io)
WAIT numreplicas timeout lets a client wait for replicas to acknowledge preceding writes on that same connection. For example, WAIT 2 1000 waits up to 1,000 milliseconds and returns the number of acknowledging replicas, which may be less than two. It reduces exposure to replication lag but neither rolls back writes when the requested count is unmet nor makes Redis strongly consistent. Failover selection is best-effort, so even a write acknowledged by several replicas can be lost. Replication acknowledgments also do not establish that those copies have been durably synchronized to storage; crash recovery remains dependent on persistence configuration. (redis.io)
Messaging, event processing, and application patterns
Redis implements the publish–subscribe pattern through named channels: PUBLISH orders.created payload sends a message to clients currently listening with SUBSCRIBE orders.created. Pattern subscriptions use glob-style matching; PSUBSCRIBE orders.*, for example, receives publications on matching channel names. Pub/Sub provides at-most-once delivery, not a retained message history: disconnected subscribers miss publications, and Redis provides neither acknowledgments nor replay for those messages. Overlapping subscriptions are a separate consideration: a client subscribed both directly to a channel and through a matching pattern can receive two notifications for one publication. Pub/Sub therefore differs from a work queue, because it broadcasts to interested subscribers rather than assigning each message to one worker. (redis.io)
Streams, introduced in Redis 5.0, are a data structure resembling an append-only event log. XADD orders * order_id 42 status created appends field–value pairs and returns an entry identifier, normally composed of a millisecond timestamp and a sequence number. Retained entries can be retrieved by identifier range with XRANGE or read after a previously recorded identifier with XREAD; unlike Pub/Sub, reading does not require being connected when the event arrives. Consumer groups distribute new entries among workers through XREADGROUP, while separate groups maintain independent consumption state. Unless acknowledgment tracking is disabled, delivered entries enter the group’s pending entries list. XACK acknowledges processing and removes the pending record, but does not itself delete the stream entry. XPENDING exposes unfinished deliveries, and claiming operations transfer ownership so another worker can retry them. This supports at-least-once processing, but repeated delivery can occur if a worker performs an external action and fails before acknowledgment. XTRIM, or trimming options on XADD, bounds retention by length or minimum identifier; replay is limited to entries still retained. (redis.io)
In caching, Redis holds replaceable copies of records whose authoritative versions reside in another database. Eviction then creates a cache miss rather than necessarily losing the underlying record: the application can retrieve and cache it again. Session storage has different consequences. A session identifier can address a Redis hash containing login context or per-user state, shared across application servers, with expiration implementing an inactivity timeout. If that hash is the only copy, memory-pressure eviction discards application-visible state and may terminate the session before its intended timeout. Expiration and eviction thus express different policies: the former defines a lifetime, whereas the latter responds to memory pressure. A noeviction policy avoids pressure-driven removal but can instead cause memory-growing writes to fail. (redis.io)
Counters and rate limiting are application patterns built from numerical operations on strings, rather than separate Redis data types. INCR page:42:views atomically increments an integer, avoiding an application-side read–modify–write sequence. A fixed-window limiter can use one key per client and second: increment the key, attach an expiration for cleanup, and reject requests when the returned count exceeds, for example, ten. Incrementing and setting expiration must be coordinated; otherwise, a client failure between INCR and EXPIRE can leave a counter without its intended lifetime. The documented implementations combine commands in a transaction or use a Lua script for conditional expiration. (redis.io)
Leaderboards similarly map application meaning onto sorted sets: members represent players and scores represent points; ZRANGE leaderboard 0 9 REV WITHSCORES retrieves the ten highest-scoring members. List-based work queues use opposite ends for first-in, first-out sequencing, such as insertion at the left and removal from the right. A simple destructive pop leaves a failure interval between removal and completed processing. LMOVE, introduced in Redis 6.2, can atomically move a job into a processing list instead; the worker removes it after success, while application logic can return overdue jobs to the waiting queue. Unlike stream consumer groups, this arrangement does not intrinsically maintain pending-delivery metadata or acknowledgments: those conventions belong to the queue implementation. (redis.io)
Deployment, observability, and security
Redis Open Source is self-managed: operators install the server and manage its configuration, capacity, persistence, upgrades, and availability arrangements. Redis Software is also self-managed, on premises or on cloud infrastructure, but supplies a commercial cluster-management platform with administrative interfaces and product-specific capabilities. Redis Cloud instead provides a managed cloud database service, transferring infrastructure and service operation to the provider while customers configure databases and application access. These deployment models do not imply identical features. For example, Redis Software’s Active-Active databases support geographically distributed writes through conflict-resolving replication; this is not a capability of an ordinary Redis Open Source installation or its primary–replica replication. (redis.io)
Observability distinguishes command execution time from the application’s end-to-end response time. SLOWLOG records commands exceeding slowlog-log-slower-than, excluding client communication I/O; consequently, an empty slow log does not establish that clients experience low latency. INFO commandstats reports per-command call counts, accumulated CPU time, and average CPU time per execution, while other INFO sections expose memory, clients, persistence, and replication measurements. The latency monitor records internal events exceeding a configurable millisecond threshold: CONFIG SET latency-monitor-threshold 100, for example, enables recording at a 100-millisecond threshold. LATENCY HISTORY exposes event samples, and LATENCY DOCTOR produces a diagnostic report. These instruments measure different aspects of server behavior rather than interchangeable definitions of latency. (redis.io)
Distinct mechanisms can produce similar response-time spikes. Commands traversing large collections can delay other command execution; persistence introduces process-forking and storage-synchronization costs; and swapping, operating-system scheduling, or hypervisor scheduling can interrupt service independently of command complexity. redis-cli --intrinsic-latency 100 measures scheduling interruptions over 100 seconds on the server host, without sending Redis requests, whereas client-side latency measurements include communication with the server. Correlating these measurements with CPU utilization, disk activity, and persistence events separates expensive database work from environmental delays. (redis.io)
Performance measurements therefore depend on the workload and test arrangement. redis-benchmark exposes controls for simultaneous connections (-c), request count (-n), value size (-d), randomized key range (-r), and pipeline depth (-P). A synchronous client awaiting each reply repeatedly pays the network round-trip cost; pipelining sends several commands before reading their replies, amortizing round trips and socket-system-call overhead. A pipeline depth of 16 describes a different workload from one outstanding request per connection, not an unconditional server speed improvement. Meaningful comparisons identify the Redis version, hardware, network placement, command mix, dataset and value sizes, concurrency, pipeline depth, and persistence configuration. A small GET/SET benchmark cannot establish universal throughput or latency for collection operations or larger datasets. (redis.io)
Redis’s security model assumes access by trusted clients, normally application servers rather than end-user browsers. Network binding and firewall restrictions establish a boundary around the service. Protected mode, introduced in version 3.2.0, rejects non-loopback clients under the documented unsecured default-configuration conditions; it is a safeguard against accidental exposure, not a replacement for access policy. Legacy requirepass authentication uses a shared password supplied through AUTH. Redis 6 introduced named users and access-control lists that restrict commands and key patterns: a newly created user granted ~cached:* +get, for example, can retrieve matching keys but cannot run SET. Authentication and authorization remain separate from Transport Layer Security (TLS), optionally supported since Redis 6 for client, replication, and cluster connections. Without TLS, AUTH credentials travel unencrypted. TLS provides transport encryption and integrity, but neither determines command permissions nor encrypts application data at rest; application-level access validation remains a separate responsibility. (redis.io)
Licensing, forks, and the wider ecosystem
Redis 7.2 and earlier release lines remain available under the BSD three-clause license. On March 20, 2024, Redis announced that subsequent releases, beginning with Redis 7.4, would instead offer a choice between the Redis Source Available License version 2 (RSALv2) and the Server Side Public License version 1 (SSPLv1). The change concerned the licensing of new releases rather than the withdrawal of BSD licensing from earlier versions. Redis’s licensing history is therefore version-specific: the continued availability of BSD-licensed Redis 7.2 does not make code introduced in Redis 7.4 available under BSD. (redis.io)
The 2024 alternatives made source code available but were not approved by the Open Source Initiative (OSI) as open-source software licenses. Their restrictions differ: RSALv2 limits specified forms of commercialization, while SSPLv1 requires providers offering the software’s functionality as a service to release service-related source code, including management layers, under its terms. Source visibility alone consequently did not establish the same permissions as an OSI-approved license. The server’s licensing change also did not automatically extend to independently licensed ecosystem components: Redis explicitly excluded language-specific client libraries and infrastructure providers from the change. Libraries such as redis-py, node-redis, and Jedis are listed under MIT licensing, while hiredis uses BSD three-clause licensing. (redis.io)
On May 1, 2025, Redis added the GNU Affero General Public License version 3 (AGPLv3) as a third option starting with Redis 8. This established an OSI-approved licensing route alongside RSALv2 and SSPLv1; recipients choose an alternative rather than complying with all three simultaneously. AGPLv3 is a copyleft license, not a return to the earlier permissive BSD model. The integrated RediSearch, RedisJSON, RedisTimeSeries, and RedisBloom components also fall under Redis 8’s three-option arrangement. These terms do not erase distinctions between release lines or products: Redis 7.2 and earlier retain BSD licensing, Redis 7.4 retains its dual-license arrangement, and commercial Redis Software and Redis Cloud remain governed by separate product agreements. (redis.io)
On March 28, 2024, the Linux Foundation announced Valkey, an independent fork based on Redis 7.2.4 that retained BSD three-clause licensing. Its initial supporters included Amazon Web Services, Google Cloud, Oracle, Ericsson, and Snap. Participants included former Redis maintainer Madelyn Olson and contributors Ping Xie and Viktor Söderqvist; the announcement described an open-governance model with a technical leadership committee containing former Redis contributors. Valkey thus continued development from a shared BSD-licensed codebase under separate stewardship, rather than becoming a differently named Redis release or a Redis commercial edition. Its announced roadmap included changes to clustering, slot migration, multithreaded performance, and commands. (linuxfoundation.org)
Compatibility within this ecosystem has several distinct layers. The Redis Serialization Protocol (RESP) defines how requests and responses are encoded; implementing RESP2 or RESP3 does not itself establish identical command coverage, semantics, persistence formats, or commercial features. Valkey’s migration documentation illustrates the distinction: it describes compatibility with Redis OSS 7.2 and earlier, including corresponding RDB snapshot and AOF persistence files, but states that RDB files produced by Redis 7.4 and later are incompatible with Valkey. A client’s ability to connect and exchange RESP messages is therefore separate from a server’s ability to execute a particular command or load a particular backup. Compatibility descriptions require both implementation and version identifiers, rather than treating “Redis-compatible” as an unrestricted equivalence. (redis.io)
References
- Redis then & now: Adapting with developers through every eraredis.io
- LLOOGG: ora completamente su Rediszzimma.antirez.com
- Redis Creator, Salvatore Sanfilippo (Antirez), Joins Redis Labsredis.io
- New Governance for Redisredis.io
- Thank You, Salvatore Sanfilipporedis.io
- Hello, Redis Stackredis.io
- Redis 8 GA: Fast, scalable, and feature-richredis.io
- Keys and valuesredis.io
- Keys and valuesredis.io
- Redis data typesredis.io
- Redis Stringsredis.io
- Redis hashesredis.io
- Compare data typesredis.io
- Redis listsredis.io
- Redis setsredis.io
- Redis sorted setsredis.io
- SISMEMBERredis.io
- HGETALLredis.io
- Redis bitmapsredis.io
- BITFIELDredis.io
- Redis geospatialredis.io
- HyperLogLogredis.io
- Bloom filterredis.io
- Cuckoo filterredis.io
- Count-min sketchredis.io
- Probabilisticredis.io
- t-digestredis.io
- JSONredis.io
- Time seriesredis.io
- TS.RANGEredis.io
- What is Redis? In-memory database, cache, and message brokerredis.io
- Diagnosing latency issuesredis.io
- Memory optimizationredis.io
- Key evictionredis.io
- EXPIREredis.io
- Redis serialization protocol specificationredis.io
- Connection pools and multiplexingredis.io
- Client toolsredis.io
- Redis pipeliningredis.io
- Transactionsredis.io
- Redis programmabilityredis.io
- Scripting with Luaredis.io
- Redis functionsredis.io
- Redis modules APIredis.io
- Modules API for native typesredis.io
- Redis persistenceredis.io
- Redis persistenceredis.io
- Redis FAQredis.io
- Diagnosing latency issuesredis.io
- SAVEredis.io
- Durable Redis technology for fast data storageredis.io
- redis-doc/docs/management/persistence.md at mastergithub.com
- BGREWRITEAOFredis.io
- Redis replicationredis.io
- High availability with Redis Sentinelredis.io
- Sentinel client specredis.io
- Scale with Redis Clusterredis.io
- Redis cluster specificationredis.io
- WAITredis.io
- Redis Pub/subredis.io
- Redis Streamsredis.io
- Redis Streamsredis.io
- Redis streaming with node-redisredis.io
- Redis streaming with redis-pyredis.io
- Redis session store with node-redisredis.io
- Redis session storeredis.io
- INCRredis.io
- ZRANGEredis.io
- LMOVEredis.io
- Install, set up, and upgrade Redis Softwareredis.io
- Redis productsredis.io
- Active-Active geo-distributed Redisredis.io
- SLOWLOGredis.io
- INFOredis.io
- Redis latency monitoringredis.io
- Redis benchmarkredis.io
- Redis securityredis.io
- ACLredis.io
- TLSredis.io
- Redis Adopts Dual Source-Available Licensingredis.io
- Licenses | Redisredis.io
- Redis is now available under the AGPLv3 open source licenseredis.io
- Linux Foundation Launches Open Source Valkey Communitylinuxfoundation.org
- valkey-doc/topics/migration.md at main · valkey-io/valkey-docgithub.com