Redis Stack (modules in Redis 8+).
Install
docker run -d -p 6379:6379 redis/redis-stack-server:latest
Or use redis-stack package (includes RedisInsight UI).
RedisJSON
JSON.SET user:1 $ '{"name":"Alice","age":30,"tags":["admin","beta"]}'
JSON.GET user:1
JSON.GET user:1 $.name
JSON.GET user:1 $..tags
JSON.SET user:1 $.age 31
JSON.ARRAPPEND user:1 $.tags '"new"'
JSON.NUMINCRBY user:1 $.age 1
JSON.DEL user:1 $.tags
JSON.OBJKEYS user:1
JSON.TYPE user:1 $.tags
RediSearch (full-text + secondary indexing)
FT.CREATE idx ON JSON PREFIX 1 user: SCHEMA $.name AS name TEXT $.age AS age NUMERIC SORTABLE $.tags[*] AS tags TAG
FT.SEARCH idx "alice"
FT.SEARCH idx "@age:[20 40]"
FT.SEARCH idx "@tags:{admin}"
FT.SEARCH idx "@name:alice @age:[25 35]"
FT.SEARCH idx "*" LIMIT 0 10 SORTBY age DESC
FT.AGGREGATE idx "*" GROUPBY 1 @tags REDUCE COUNT 0 AS c
Used by Redis OM clients (Python/Node).
Vector search
FT.CREATE idx ON HASH SCHEMA embedding VECTOR HNSW 6 TYPE FLOAT32 DIM 1536 DISTANCE_METRIC COSINE
r.hset(f"doc:{i}", mapping={
"text": text,
"embedding": np.array(embed(text), dtype=np.float32).tobytes(),
})
# Query
q_vec = np.array(embed(query), dtype=np.float32).tobytes()
res = r.execute_command(
"FT.SEARCH", "idx",
"*=>[KNN 5 @embedding $vec AS score]",
"PARAMS", "2", "vec", q_vec,
"RETURN", "2", "text", "score",
"DIALECT", "2",
)
Hybrid (text + vector)
FT.SEARCH idx "@category:{news}=>[KNN 5 @embedding $vec]"
TimeSeries
TS.CREATE temp:nyc RETENTION 86400000 LABELS city ny
TS.ADD temp:nyc * 23.5
TS.MADD temp:nyc 1700000000 22 temp:la 1700000000 28
TS.RANGE temp:nyc - + AGGREGATION avg 60000
TS.MRANGE - + AGGREGATION avg 60000 FILTER city=ny
TS.CREATERULE temp:nyc temp:nyc:hourly AGGREGATION avg 3600000
Time-series storage in Redis.
Bloom filters
BF.RESERVE filter 0.01 1000
BF.ADD filter "item"
BF.EXISTS filter "item"
BF.MEXISTS filter "a" "b" "c"
BF.SCANDUMP / BF.LOADCHUNK
For “have I seen this?” with bounded memory.
Cuckoo filters
Like Bloom but supports delete:
CF.RESERVE filter 1000
CF.ADD filter "a"
CF.DEL filter "a"
CF.EXISTS filter "a"
Count-min sketch
CMS.INITBYDIM cms 1000 5
CMS.INCRBY cms "a" 1 "b" 5
CMS.QUERY cms "a" "b"
Approximate frequency counter.
Top-K
TOPK.RESERVE topk 10 1000 5 0.9
TOPK.ADD topk "a" "b" "a" "c"
TOPK.LIST topk
TOPK.COUNT topk "a"
Graphs (RedisGraph)
GRAPH.QUERY social "CREATE (:Person {name:'Alice'})-[:KNOWS]->(:Person {name:'Bob'})"
GRAPH.QUERY social "MATCH (p:Person)-[:KNOWS]->(f) RETURN p.name, f.name"
(Note: RedisGraph deprecated; consider FalkorDB / Neo4j.)
Common uses
- JSON-doc store with search → mini Mongo.
- Vector for embeddings.
- Bloom for dedup / quick membership.
- TimeSeries for metrics.
Common mistakes
- Using OSS Redis with Stack commands → unknown command.
- Index per query (create once).
- Forgetting to update index on schema change.
- Vector field binary encoding wrong dim/dtype.
Read this next
If you want my Stack-based search setup, it’s at rajpoot.dev .
Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .