Lists, Sets, Sorted Sets, Arrays & Geospatial
|
This content was generated with the assistance of AI and should be verified against the official Redis documentation before being relied on in production. This section’s bibliography lists the reference material consulted while preparing these pages. |
Redis’s collection types share the same key-value model — one key names the whole structure — but differ in how their elements are ordered and addressed: a List keeps insertion order, a Set has none, a Sorted Set orders its members by an attached score, and an Array addresses elements by an integer index the way a fixed-size buffer does. Geospatial indexing reuses the Sorted Set internally rather than adding a distinct type. Examples on this page target Redis Open Source 8.10 (8.10.2), against Jedis 8 and Lettuce 7.7.
Lists
A List is a doubly-linked sequence of strings, pushed and popped from either end in O(1) time.
-
LPUSH key element [element …]/RPUSH key element [element …]— insert one or more elements at the head or tail. LPUSH / RPUSH. -
LPOP key [count]— remove and return one orcountelements from the head;RPOPis the tail-side mirror. LPOP. -
BRPOP key [key …] timeout— the blocking form ofRPOP: waits up totimeoutseconds for an element to appear in the first non-empty key given, instead of returning immediately when the list is empty. BRPOP. -
LMOVE source destination LEFT|RIGHT LEFT|RIGHT— atomically pops one element fromsourceand pushes it todestination, in a single round trip.BLMOVEis its blocking counterpart, waiting up totimeoutseconds forsourceto produce an element. LMOVE / BLMOVE. -
LMOVEM source destination LEFT|RIGHT LEFT|RIGHT [<COUNT count | EXACTLY exactly> <OBO | BULK>]— new in Redis 8.10, this is the multi-element version ofLMOVE: without the optional block it behaves exactly likeLMOVE, but with it moves several elements atomically in one call.COUNTmoves up to that many elements (fewer ifsourceis shorter);EXACTLYmoves precisely that many or nothing, returning nil ifsourcedoes not hold enough — useful when elements form fixed-size groups that must move together.OBO(one by one) andBULKcontrol the resulting order ondestination:OBOmoves elements individually (and, whensourceanddestinationare the same key, reverses them in place),BULKmoves the whole batch at once, preserving relative order.BLMOVEMis the blocking counterpart. LMOVEM. -
LTRIM key start stop— trims a list down to the elements betweenstartandstop(inclusive, zero-based, negative indexes count from the tail), discarding everything outside that range. Run after every push, it caps a list’s size in O(N) proportional to the number of elements removed. LTRIM.
Example: recently viewed books, capped with LTRIM
Every book view pushes an ISBN onto bookshop:recent:<userId>, then LTRIM caps the list at the 20 most
recent entries so it never grows unbounded:
127.0.0.1:6379> LPUSH bookshop:recent:42 9780000000003
(integer) 1
127.0.0.1:6379> LTRIM bookshop:recent:42 0 19
OK
127.0.0.1:6379> LRANGE bookshop:recent:42 0 -1
1) "9780000000003"
See LTRIM and Redis lists for the full list reference this example derives from.
Sets
A Set is an unordered collection of unique strings, with O(1) average membership tests.
-
SADD key member [member …]— add one or more members, ignoring ones already present. SADD. -
SISMEMBER key member— test membership in O(1).SMISMEMBERtests several members in one call. SISMEMBER. -
SINTER key [key …]— returns the members present in every given set. SINTER. -
SUNIONCARD numkeys key [key …] [LIMIT limit]— the count-only counterpart ofSUNION: returns just the number of distinct members in the union, without materializing it, optionally stopping early oncelimitmembers are counted. It also acceptsAPPROX, which estimates the cardinality with HyperLogLog for large unions instead of computing it exactly. SUNIONCARD. -
SDIFFCARD numkeys key [key …] [LIMIT limit]— new in Redis 8.10, the count-only counterpart ofSDIFF: returns the number of members in the first set that are absent from every subsequent set, again with an optional early-stoppingLIMIT. SDIFFCARD. -
SRANDMEMBER key [count]— returns one orcountrandom members without removing them; a positivecountnever repeats a member, a negativecountmay. SRANDMEMBER.
SUNIONCARD and SDIFFCARD both let an application ask "how many" without paying to transfer and re-count the
member list on the client, which is what SUNION/SDIFF piped through a client-side count would otherwise
cost.
Sorted sets
A Sorted Set (ZSET) pairs each unique member with a floating-point score and keeps members ordered by score,
backed by a skip list plus a hash table, so both score-ordered range scans and by-member lookups are efficient.
-
ZADD key score member [score member …]— add or update scored members;GT/LT/NX/XXflags constrain when an existing score is overwritten, andINCRturns it into an increment. This is the primary write for the best-sellers example below. ZADD. -
ZRANGE key start stop [BYSCORE | BYLEX] [REV] [LIMIT offset count] [WITHSCORES]— reads a range of members. By defaultstart/stopare rank indexes;BYSCOREinterprets them as a score range instead (-inf/+infand(for exclusive bounds),BYLEXas a lexicographic range over equally-scored members, andREVreverses the scan from highest to lowest. This single command replaces the olderZRANGEBYSCORE/ZREVRANGE/ZRANGEBYLEXfamily. ZRANGE. -
ZRANK key member [WITHSCORE]— returns a member’s 0-based rank in ascending score order (ZREVRANKfor descending), optionally with its score in the same reply. ZRANK. -
ZINCRBY key increment member— atomically addsincrementto a member’s score, creating the member with that score if it is not already present. ZINCRBY. -
ZPOPMIN key [count]— removes and returns thecountmembers with the lowest scores;ZPOPMAXmirrors it at the high end. ZPOPMIN. -
BZMPOP timeout numkeys key [key …] MIN|MAX [COUNT count]— the blocking, multi-key pop: waits up totimeoutseconds, then pops from the first of the given keys that is non-empty, taking the lowest (MIN) or highest (MAX) scoring members. BZMPOP. -
ZUNION numkeys key [key …] [WEIGHTS w [w …]] [AGGREGATE SUM|MIN|MAX] [WITHSCORES]and the equivalentZINTER— combine several sorted sets, scoring a member present in more than one input by the chosenAGGREGATEfunction (SUMby default) over its optionallyWEIGHTS-scaled input scores. ZUNION / ZINTER.
Example: best-sellers, a sorted set scored by units sold
bookshop:bestsellers scores each ISBN by units sold; ZINCRBY records a sale, and a reversed ZRANGE reads
the top 10:
127.0.0.1:6379> ZINCRBY bookshop:bestsellers 1 9780000000001
"1"
127.0.0.1:6379> ZADD bookshop:bestsellers 42 9780000000002 17 9780000000003
(integer) 2
127.0.0.1:6379> ZRANGE bookshop:bestsellers 0 9 REV WITHSCORES
1) "9780000000002"
2) "42"
3) "9780000000003"
4) "17"
5) "9780000000001"
6) "1"
See ZINCRBY, ZRANGE, and Redis sorted sets for the reference this example derives from.
The Array type
Redis 8.8 added Array as a distinct data type from List: a sparse, index-addressable structure that maps
integer indexes (0 to 264-1) to string values, giving O(1) access to any index instead of a List’s O(N)
positional access. Because indexes can be set out of order and gaps are left unallocated, an Array suits
timestamped event logs, ring buffers over streaming measurements, and sliding-window analytics — workloads
that need direct addressing rather than sequential push/pop, which is exactly where a List, Hash (no position
concept), or Sorted Set (scores are metadata, not addresses) falls short.
Its 18 commands split into a few groups:
-
Point access:
ARSET key index value [value …]writes one or more contiguous values starting atindex;ARGET key indexreads a single index, returning nil if unset. ARSET / ARGET. -
Scattered access:
ARMSET key index value [index value …]writes arbitrary, non-contiguous indexes in one call;ARMGET key index [index …]reads several indexes in one round trip. ARMSET / ARMGET. -
Size and metadata:
ARLEN keyreturns the logical length (highest set index + 1);ARCOUNT keyreturns the number of non-empty elements — the two diverge sharply on a sparse array.ARINFO key [FULL]returns the array’s metadata (count, length, next insert index, slice layout), andFULLadds per-slice dense/sparse statistics at O(N) cost. ARLEN / ARCOUNT / ARINFO. -
Ranges and iteration:
ARGETRANGE key start stopreads a contiguous range, including nil for unset slots;ARSCAN key start stopiterates only the elements that exist, returning index-value pairs. ARGETRANGE / ARSCAN. -
Cursor-based append and ring buffers:
ARINSERTappends at an auto-advancing cursor (ARNEXTreads it,ARSEEKrepositions it);ARRING key size value [value …]maintains a fixed-size circular buffer that overwrites the oldest entry once full, paired withARLASTITEMS key count [REV]to read back the most recently inserted elements. ARRING / ARLASTITEMS. -
Search, aggregate, and delete:
ARGREPsearches a range with textual predicates (EXACT/MATCH/GLOB/RE, combinable withAND/OR);AROPruns a single-pass aggregate (such asSUM,MAX, or a match count) over a contiguous range;ARDEL key index [index …]deletes specific indexes andARDELRANGEdeletes a whole index range. ARGREP / AROP.
Reach for an Array instead of a List when the access pattern is "read or write position N directly" — a sliding window, a ring buffer of the last N measurements, or a sparse timestamp-indexed log — and reach for a List when the access pattern is genuinely sequential push/pop from either end. Full command list and walkthrough: Redis arrays.
Geospatial
Geospatial indexing is not a separate storage engine: GEOADD stores each member in an ordinary Sorted Set,
scored by a 52-bit interleaved geohash of its longitude/latitude, so every Sorted Set command (ZRANGE,
ZSCORE, ZREM, and so on) already works against a geo key. The geo commands are a convenience layer that
encodes/decodes that geohash and runs the radius/box math on top.
-
GEOADD key longitude latitude member [longitude latitude member …]— adds or updates members' coordinates. GEOADD. -
GEOPOS key member [member …]— returns each member’s stored longitude/latitude, decoded back from its geohash score. GEOPOS. -
GEODIST key member1 member2 [M | KM | FT | MI]— the distance between two members, in the given unit (metres by default). GEODIST. -
GEOSEARCH key <FROMMEMBER member | FROMLONLAT longitude latitude> <BYRADIUS radius unit | BYBOX width height unit> [ASC | DESC] [COUNT count [ANY]] [WITHCOORD] [WITHDIST] [WITHHASH]— searches for members inside a circle (BYRADIUS) or an axis-aligned box (BYBOX) around a member or an explicit point.GEOSEARCHis the modern replacement for the deprecatedGEORADIUS/GEORADIUSBYMEMBERcommands and should be used in their place. GEOSEARCH. -
GEOSEARCHSTORE destination source <FROMMEMBER member | FROMLONLAT longitude latitude> <BYRADIUS radius unit | BYBOX width height unit> […] [STOREDIST]— runs the same search asGEOSEARCHbut writes the matches intodestinationas a new sorted set instead of returning them, optionally storing distance rather than the geohash as the score (STOREDIST). GEOSEARCHSTORE.
The Query Engine indexes geospatial data differently again, through GEO and GEOSHAPE field types on a JSON
or hash document rather than a member of a sorted set; see
Query Engine: Indexing & Data Modeling for that indexing path.
Example: nearest store lookup
bookshop:stores is a geo key mapping store IDs to coordinates; GEOSEARCH finds every store within 10 km of
a customer’s location, nearest first:
127.0.0.1:6379> GEOADD bookshop:stores 2.3522 48.8566 "store:paris-1"
(integer) 1
127.0.0.1:6379> GEOADD bookshop:stores 2.2945 48.8584 "store:paris-2"
(integer) 1
127.0.0.1:6379> GEOSEARCH bookshop:stores FROMLONLAT 2.3200 48.8600 BYRADIUS 10 km ASC WITHDIST
1) 1) "store:paris-2"
2) "1.8745"
2) 1) "store:paris-1"
2) "2.3865"
See GEOSEARCH and Redis geospatial for the reference this example derives from.
Structures compared
| Type | Ordering | Key operations | Typical complexity |
|---|---|---|---|
List |
Insertion order |
|
O(1) at either end, O(N) for an index or a trim |
Set |
None |
|
O(1) add/test, O(N) for a multi-set combination |
Sorted Set |
By score |
|
O(log N) add/rank, O(log N + M) for a range of M members |
Array |
By integer index |
|
O(1) per index, O(N) for a contiguous range |
Geospatial |
By geohash score (a Sorted Set) |
|
O(N + log M) for a search over N candidates and M matches |
Related pages
-
Use Cases & Patterns — caching, session storage, and rate-limiting patterns that build on these structures.
-
Query Engine: Indexing & Data Modeling — indexing JSON/hash documents, including the
GEO/GEOSHAPEfield types that complement the geohash-on-a-sorted-set approach described here.