NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #3066 most downloaded on PyPI
Python client library and CLI for using Redis as a vector database
Last release 24 days ago
10 Sep 2026
Ships fairly regularly
a new release about every 2 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
3 versions withdrawn
withdrawn after publishing
3 years old
64 releases · first in 2023
One column per quarter.
fix: permit clear() when create_index=False, and drop its FT.INFO dependency
SemanticCache, MessageHistory, SemanticMessageHistory and SemanticRouter constructed with create_index=False can now call clear() to remove their entries. Previously both clear() and delete() raised ValueError under that flag; delete() still does, because it drops the index. This is a behavioural change: code that caught ValueError from clear() and treated it as "unavailable" will now delete data.
SearchIndex.clear() and AsyncSearchIndex.clear() no longer issue FT.INFO. They size their internal delete loop with a CountQuery instead, so clearing an index is available to a credential built from +@read +@write, which is denied FT.INFO. Clearing also no longer stops early on a page whose keys could not be deleted.
EXTERNAL_INDEX_LIFECYCLE_CONFLICT in redisvl.extensions.constants is renamed to EXTERNAL_INDEX_DROP_CONFLICT, and its message has changed. Code importing the old name, or matching on the old text, needs updating.
paginate going past a page whose matches were all dropped #701 @vishal-balaThis is a security release. Upgrade if any filter value in your application comes from user input.
This is a security release. Upgrade if any filter value in your application comes from user input.
Every filter class rendered a caller's value into its RediSearch clause without containing it, so a crafted value could close that clause and append its own syntax. Under DIALECT 2 an injected | lifts to the root of the query, which means a surrounding tenant or visibility filter stopped applying and the query returned records outside its scope. Tag, Text, Num and Geo were each reachable by a different route, and all four now validate the value where it is supplied. Detail in GHSA-932c-v3f4-cwxp.
Filter expressions are also parenthesised now wherever they combine with another clause, which fixes three broken query shapes.
Check these before you upgrade.
| Call | Before | Now |
|---|---|---|
Text("f") != value, quote in the value |
excluded nothing | excludes correctly |
GeoRadius(lon, lat, 1.9, "km") |
queried 1 km | queries 1.9 km |
MCP text filters eq, ne, in, multi-word value |
matched nothing | work as intended |
A | in a tag value is now escaped, so Tag("f") == "a|b" matches that one literal value rather than either a or b. Pass a list for a union: Tag("f") == ["a", "b"] is unchanged.
A VectorRangeQuery with a raw-string filter containing a top-level | returned documents outside the vector range, because the union bound across the intersection rather than inside the filter. It now returns fewer, correctly filtered results.
Num(field).between(start, end) raises TypeError unless both bounds are real numbers, so coerce a numeric string or a Decimal first. int, float and numpy scalars are unaffected.TypeError for a str or Decimal, and ValueError outside their range.ValueError.A VectorQuery whose filter_expression holds more than one clause, and a MultiVectorQuery given an explicit wildcard filter, both raised a syntax error.
A filtered MultiVectorQuery no longer groups its vector-range clauses in parentheses, and a filtered VectorRangeQuery no longer wraps the whole query. Same meaning, different string. Tests asserting on exact query strings may need updating.
The pattern operators still interpolate their input raw, which is what makes *, %% and | work: Text(field) % pattern, Tag(field) % pattern and TextQuery(text=...) all behave as before. Do not pass untrusted input to them; use == for a value you did not construct.
feat(mcp): declarative custom tool profiles over search-records
The RedisVL MCP server can now publish custom tool profiles: additional tools defined entirely in the server's YAML configuration, with no Python required. A profile specialises the built-in search-records under a name and description you choose, pinning the index it targets and freezing whichever arguments you want fixed.
An author can lock the filter, the returned field set and a maximum result count, and choose per argument whether the model may pass it. A locked filter is AND-combined with any filter the model supplies, so the model can narrow the search but cannot widen or remove the locked clause; locked and hidden arguments are absent from the tool's advertised input schema, so there is no argument name for the model to pass. Profiles execute through the same path as the built-in tool and inherit its concurrency limit, request timeout, read-only enforcement, auth scoping and error contract.
Configuration errors fail at server startup with an actionable message rather than at the first tool call, and unrecognised keys in a profile are rejected rather than ignored.
This is additive. Existing configurations are unaffected, and a server with no custom_tools block behaves exactly as before.
redis-py 5.x and 6.0-6.2 are no longer supported. Upgrade to redis-py 6.3 or later. redis-py 8.0.0 is excluded because of its RESP3 empty-search-results defect.
feat: let callers opt out of index creation with create_index=False #687 @vishal-bala @nkanu17
fix: check index existence with FT.INFO instead of listing every index #672 @vishal-bala
Timestamp date filters now return different rows (affected versions 0.5.1–0.25.0). With a bare date or date-only string, != matched the day it was asked to exclude, > behaved like >=, and <= behaved like <. Day boundaries also followed the host timezone rather than UTC, so the same filter resolved differently by machine. All of it failed silently. If you compensated for the old behavior, remove the workaround; if you assert on generated query strings, expect them to change. datetime, full ISO string, and Unix timestamp filters were never affected.
exists() now raises RedisSearchError instead of leaking raw redis-py exceptions. create() already wrapped every other Redis failure this way; the existence check was the one path that escaped. Code catching redis.exceptions.ResponseError around create() — or around a SemanticCache, MessageHistory, SemanticMessageHistory, or SemanticRouter constructor, all of which call create() — should catch RedisSearchError and read __cause__ for the original. This includes NoPermissionError handlers, since that subclasses ResponseError.
fix: prevent SearchIndex/AsyncSearchIndex finalizer from leaking every instance #657 @nkanu17
Memory leak fixed (affected versions 0.4.0–0.24.0). SearchIndex/AsyncSearchIndex instances were never garbage-collected due to a self-referencing cleanup callback, causing unbounded memory growth in services that create indexes per request or operation. This release fixes the underlying issue; on older versions, reusing a single long-lived index instance or supplying a caller-owned Redis client (redis_client=...) avoids the leak — disconnect() does not.
feat: enable client-side bulk update/delete operations with SearchIndex (RAAE-1326) #651 @vishal-bala
SearchIndex (RAAE-1326) #651 @vishal-balafeat(mcp): multi-index MCP server support (RAAE-1603) #646 ( @vishal-bala )
test: Add regression coverage for RedisVL CLI foundation contracts #596 ( @limjoobin @hillarytoh )
make add_route public #624 ( @rbs333 )
feat: Index Migrator #583 ( @nkanu17 )
feat: add Ollama text vectorizer #617 ( @s-agbede )
update for sql-redis 0.5.0 #598 (@rbs333)
docs(cli): Clean up CLI command structure and improve documentation #594 (@limjoobin @vishal-bala)
rvl index and rvl stats now require shared flags such as --url, --host, and --json to appear after the subcommand (for example, rvl index listall --url ...) rather than supporting them being placed before it.
refactor(python): drop Python 3.9 support #587 (@vishal-bala)
feat(mcp): add Streamable HTTP and SSE transport support by @nkanu17 in https://github.com/redis/redis-vl-python/pull/580
Full Changelog: https://github.com/redis/redis-vl-python/compare/v0.17.0...v0.17.1
feat(MCP): Introduce a configurable MCP server for RedisVL indexes #575 (@vishal-bala)
ci(release): Run automated release workflows outside PR context by @vishal-bala in https://github.com/redis/redis-vl-python/pull/513
count()support to message history by @GDaamn in https://github.com/redis/redis-vl-python/pull/517Full Changelog: https://github.com/redis/redis-vl-python/compare/v0.15.0...v0.16.0
ci: Remove deprecated auto configuration field #505 (@vishal-bala)
auto configuration field #505 (@vishal-bala)auto workflow #504 (@vishal-bala)auto (dry-run for now) #482 (@vishal-bala)Nothing published for this version
ci: Minor clean-ups for GH Actions workflow for testing fork PRs
We'd like to thank all the contributors who worked on this release!
@dfroger, @rbs333 and @vishal-bala
This releases fixes a bug where the redisvl.utils.vectorize module had an unintentional dependency on the botocore package.
This releases fixes a bug where the redisvl.utils.vectorize module had an unintentional dependency on the botocore package.
Added HybridQuery interface for FT.HYBRID search command introduced in Redis 8.4.0 (#447, #455)
HybridQuery interface for FT.HYBRID search command introduced in Redis 8.4.0 (#447, #455)SemanticCache().check and .acheck (#446)redisvl.extensions.message_history.schema.ChatMessage ID-generation could encounter collisions if multiple messages were added rapidly with the same timestamp, resulting in potential message loss (#450)We'd like to thank all the contributors who worked on this release!
@abrookins, @dfroger, @nkanu17 and @vishal-bala
Add runtime parameter support for HNSW and SVS-VAMANA vector indexes
We'd like to thank all the contributors who worked on this release!
@nkanu17
Add index level stopwords support in configuration in index schema
We'd like to thank all the contributors who worked on this release!
@abrookins and @nkanu17
Fix LangCache clear() 400 error by using flush() API
We'd like to thank all the contributors who worked on this release!
@Copilot, @abrookins, @copilot-swe-agent, @nicoweidner and @vinaykulk621
Add LangCache integration (LLM cache extension) (#408, #418)
We'd like to thank all the contributors who worked on this release!
@abrookins, @justin-cechmanek and @nkanu17
We'd like to thank all the contributors who worked on this release!
We'd like to thank all the contributors who worked on this release!
@justin-cechmanek and @rbs333
refactor: obtain version information dynamically from the installed p…
We'd like to thank all the contributors who worked on this release!
@bsbodden
Fixed pytest warnings and deprecation notices
Release Date: October 1, 2025
We're excited to announce RedisVL 0.9.0, featuring significant enhancements to conversational AI, advanced query capabilities, and enterprise-grade reliability improvements.
Your AI agents and chatbots now have more powerful memory capabilities:
tool role alongside system, user, and llm roles, enabling proper function calling workflows# Filter by role
history.get_recent(role="user") # Only user messages
history.get_recent(role=["system", "llm"]) # System and LLM messages
# Add metadata to messages
history.add_message({
"role": "tool",
"content": "42",
"tool_call_id": "calc_001",
"metadata": {"function": "calculate", "duration_ms": 15}
})
Impact: Build more sophisticated AI agents with better observability and control over conversational context.
Prioritize matches in specific fields (like titles over content) with customizable weights:
from redisvl.query import TextQuery
query = TextQuery(
text="machine learning tutorial",
text_field_name={
"title": 5.0, # Boost title matches 5x
"description": 2.0, # Boost description 2x
"content": 1.0 # Normal content weight
}
)
Enhanced sort_by() API with support for multiple formats:
# Simple ascending sort
query.sort_by("score")
# With explicit direction
query.sort_by(("created_at", "DESC"))
# Multiple fields (first field used per Redis limitations)
query.sort_by([("score", "DESC"), ("created_at", "ASC")])
Skip decoding for embeddings and other binary data:
query.return_fields(
["title", "content", "embedding"],
skip_decode="embedding" # Return raw bytes
)
Impact: More precise search relevance and better performance when working with binary data.
High availability deployments with automatic failover:
from redisvl.index import SearchIndex
index = SearchIndex(
schema,
redis_url="redis+sentinel://sentinel1:26379,sentinel2:26379/mymaster"
)
Supports multiple sentinel hosts, authentication, and database selection.
Fine-grained control over indexing and sorting behavior:
no_index - Store sortable fields without indexing (reduces memory, maintains sort capability)unf (Un-Normalized Form) - Preserve original case/format for sorting on text and numeric fieldsfields:
- name: display_name
type: text
attrs:
sortable: true
unf: true # Case-sensitive sorting
no_index: false # Still searchable
Impact: Better support for production deployments and optimized index memory usage.
SearchIndex.from_existing() - eliminated duplicate validation callsImpact: Faster index operations and reduced Redis command overhead, especially noticeable in high-connection scenarios.
SearchIndex.from_existing() - now properly captures all prefixes instead of just the first oneuser::123 → user:123)cluster parameter that's incompatible with AsyncRedisCluster.from_url()nodes_manager attributeImpact: More reliable operation across different Redis deployment types and improved stability.
None - This release maintains full backward compatibility with 0.8.x versions.
All new features are additive with sensible defaults that preserve existing behavior.
pip install --upgrade redisvl
For optional dependencies:
pip install redisvl[all] # All vectorizer dependencies
pip install redisvl[hiredis] # High-performance parser
Thank you to everyone who contributed to this release:
Special thanks to our users who provided feedback and feature requests that shaped this release.
Full Changelog: https://github.com/redis/redis-vl-python/compare/v0.8.2...v0.9.0
Filter expression as native string
We'd like to thank all the contributors who worked on this release!
@rbs333
disable progress bar by default
We'd like to thank all the contributors who worked on this release!
@justin-cechmanek and @rbs333
Migrate from poetry to UV for improved dependency mgmt
We'd like to thank all the contributors who worked on this release!
@NishithHM, @abrookins, @fzowl, @paololazzari and @tylerhutcherson
Fix various commands to work with Redis Cluster
We'd like to thank all the contributors who worked on this release!
@abrookins and @tylerhutcherson
Embeddings Cache Support Embedding caching is now enabled across all vectorizers, improving performance and reusability. (#318, #320, #325)
Embeddings Cache Support
Embedding caching is now enabled across all vectorizers, improving performance and reusability.
(#318, #320, #325)
Semantic Router Enhancements
Reference updates are now supported in semantic routers.
(#322)
Lazy Import Strategy
Introduced a lazy_import utility to defer loading of third-party libraries.
(#330, #331)
New Default Embeddings Model
Changed the default embedding model for semantic caching. See our published research on this model on arxiv.
(#326)
Refactored Naming
Renamed session manager classes to more clearly reflect their role as message history managers.
(#323)
Dependency Cleanup
Removed unnecessary third-party libraries (tabulate, coloredlogs) to reduce bloat.
(#329)
@abrookins, @justin-cechmanek, @rbs333, and @tylerhutcherson
Full Changelog: https://github.com/redis/redis-vl-python/compare/0.5.2...v0.6.0
Fix HybridQuery class description
We'd like to thank all the contributors who worked on this release!
@paololazzari and @tylerhutcherson
Add helpers for full-text and hybrid search queries
We'd like to thank all the contributors who worked on this release!
@abrookins, @bsbodden, @justin-cechmanek, @rbs333 and @tylerhutcherson
Nothing published for this version
We'd like to thank all the contributors who worked on this release!
We'd like to thank all the contributors who worked on this release!
@abrookins and @rbs333
Patch dependabot security vulnerability in extras dependency
We'd like to thank all the contributors who worked on this release!
@abrookins, @justin-cechmanek, @rbs333 and @tylerhutcherson
Integrate VoyageAI Vectorizer and Reranker class
dtype field of BaseVectorizer (#261)We'd like to thank all the contributors who worked on this release!
@abrookins, @joshrotenberg and @tylerhutcherson
fix protobuf broken version for google (optional) dependencies by @tylerhutcherson in https://github.com/redis/redis-vl-python/pull/254
Full Changelog: https://github.com/redis/redis-vl-python/compare/0.3.7...0.3.8
updates github link repo name in docs by @justin-cechmanek in https://github.com/redis/redis-vl-python/pull/241
Full Changelog: https://github.com/redis/redis-vl-python/compare/0.3.6...0.3.7
Expose show_progress_bar by @antonum in https://github.com/redis/redis-vl-python/pull/236
Full Changelog: https://github.com/redis/redis-vl-python/compare/0.3.5...0.3.6
Fix sentence transformers reranker import by @tylerhutcherson in https://github.com/redis/redis-vl-python/pull/231
Full Changelog: https://github.com/redis/redis-vl-python/compare/0.3.4...0.3.5
DOC-4198: add TCEs to the vector query page by @dwdougherty in https://github.com/redis/redis-vl-python/pull/221
Full Changelog: https://github.com/redis/redis-vl-python/compare/0.3.3...0.3.4
Refactor query classes by @tylerhutcherson in https://github.com/redis/redis-vl-python/pull/211
Full Changelog: https://github.com/redis/redis-vl-python/compare/0.3.2...0.3.3
Fix cache schema overwrite by @justin-cechmanek in https://github.com/redis/redis-vl-python/pull/208
Full Changelog: https://github.com/redis/redis-vl-python/compare/0.3.1...0.3.2
Fix semantic cache with empty metadata by @tylerhutcherson in https://github.com/redis/redis-vl-python/pull/201
Full Changelog: https://github.com/redis/redis-vl-python/compare/0.3.0...0.3.1
adds check to ensure correct embedding vector dimensions are used by @justin-cechmanek in https://github.com/redis/redis-vl-python/pull/177
Full Changelog: https://github.com/redis/redis-vl-python/compare/0.2.3...0.3.0
Fix index loading empty array by @tylerhutcherson in https://github.com/redis/redis-vl-python/pull/173
Full Changelog: https://github.com/redis/redis-vl-python/compare/0.2.2...0.2.3
Fix null numeric filter conditions by @bsbodden in https://github.com/redis/redis-vl-python/pull/164
Full Changelog: https://github.com/redis/redis-vl-python/compare/0.2.1...0.2.2
temporarily disable codecov failures by @tylerhutcherson in https://github.com/redis/redis-vl-python/pull/153
Full Changelog: https://github.com/redis/redis-vl-python/compare/0.2.0...0.2.1
Add support for AzureOpenAI by @ajac-zero in https://github.com/RedisVentures/redisvl/pull/131
Full Changelog: https://github.com/RedisVentures/redisvl/compare/0.1.3...0.2.0
fix connection pool for SSL by @tylerhutcherson in https://github.com/RedisVentures/redisvl/pull/129
Full Changelog: https://github.com/RedisVentures/redisvl/compare/0.1.2...0.1.3
Added ACRE to README by @MSFTeegarden in https://github.com/RedisVentures/redisvl/pull/124
Full Changelog: https://github.com/RedisVentures/redisvl/compare/0.1.1...0.1.2
Update Cohere client setting by @nabsabraham in https://github.com/RedisVentures/redisvl/pull/118
Full Changelog: https://github.com/RedisVentures/redisvl/compare/0.1.0...0.1.1
Fixing release drafter to work aginst the main branch by @chayim in https://github.com/RedisVentures/redisvl/pull/102
Full Changelog: https://github.com/RedisVentures/redisvl/compare/0.0.7...0.1.0
0.0.6 Release by @Spartee in https://github.com/RedisVentures/redisvl/pull/100
Full Changelog: https://github.com/RedisVentures/redisvl/compare/0.0.5...0.0.7
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →