From 1e8cebf1352b3132783f481e26738eef58bff8cb Mon Sep 17 00:00:00 2001 From: LizerAIDev Date: Thu, 14 May 2026 12:41:26 +0000 Subject: [PATCH 1/2] perf: replace DELETE with UNLINK in EmbeddingsCache for better memory management - Replace client.delete() with client.unlink() in drop_by_key - Replace pipeline.delete() with pipeline.unlink() in mdrop_by_keys - Replace await client.delete() with await client.unlink() in async methods - UNLINK frees memory asynchronously, avoiding blocking the Redis server - Improves performance for high-throughput cache invalidation scenarios --- redisvl/extensions/cache/embeddings/embeddings.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/redisvl/extensions/cache/embeddings/embeddings.py b/redisvl/extensions/cache/embeddings/embeddings.py index 7218de5c..d14280bf 100644 --- a/redisvl/extensions/cache/embeddings/embeddings.py +++ b/redisvl/extensions/cache/embeddings/embeddings.py @@ -512,6 +512,8 @@ def drop(self, content: bytes | str, model_name: str) -> None: def drop_by_key(self, key: str) -> None: """Remove an embedding from the cache by its Redis key. + Uses UNLINK instead of DELETE for better performance by freeing memory asynchronously. + Args: key (str): The full Redis key for the embedding. @@ -520,7 +522,7 @@ def drop_by_key(self, key: str) -> None: cache.drop_by_key("embedcache:1234567890abcdef") """ client = self._get_redis_client() - client.delete(key) + client.unlink(key) def mdrop_by_keys(self, keys: list[str]) -> None: """Remove multiple embeddings from the cache by their Redis keys. @@ -542,7 +544,7 @@ def mdrop_by_keys(self, keys: list[str]) -> None: with client.pipeline(transaction=False) as pipeline: for key in keys: - pipeline.delete(key) + pipeline.unlink(key) pipeline.execute() def mdrop(self, contents: Iterable[bytes | str], model_name: str) -> None: @@ -883,7 +885,7 @@ async def amdrop_by_keys(self, keys: list[str]) -> None: return client = await self._get_async_redis_client() - await client.delete(*keys) + await client.unlink(*keys) async def amdrop(self, contents: Iterable[bytes | str], model_name: str) -> None: """Async remove multiple embeddings from the cache by their contents and model name. @@ -982,4 +984,4 @@ async def adrop_by_key(self, key: str) -> None: await cache.adrop_by_key("embedcache:1234567890abcdef") """ client = await self._get_async_redis_client() - await client.delete(key) + await client.unlink(key) From 1ab884671d98e823f4b7bce39d88bca9aca29048 Mon Sep 17 00:00:00 2001 From: LizerAIDev Date: Thu, 14 May 2026 17:31:57 +0000 Subject: [PATCH 2/2] perf: use UNLINK instead of DEL in SearchIndex.drop_keys Fixes #600 --- redisvl/index/index.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/redisvl/index/index.py b/redisvl/index/index.py index 4d7a871b..5b2e0898 100644 --- a/redisvl/index/index.py +++ b/redisvl/index/index.py @@ -833,9 +833,9 @@ def drop_keys(self, keys: str | list[str]) -> int: int: Count of records deleted from Redis. """ if isinstance(keys, list): - return self._redis_client.delete(*keys) # type: ignore + return self._redis_client.unlink(*keys) # type: ignore else: - return self._redis_client.delete(keys) # type: ignore + return self._redis_client.unlink(keys) # type: ignore def drop_documents(self, ids: str | list[str]) -> int: """Remove documents from the index by their document IDs. @@ -1787,9 +1787,9 @@ async def drop_keys(self, keys: str | list[str]) -> int: """ client = await self._get_client() if isinstance(keys, list): - return await client.delete(*keys) + return await client.unlink(*keys) else: - return await client.delete(keys) + return await client.unlink(keys) async def drop_documents(self, ids: str | list[str]) -> int: """Remove documents from the index by their document IDs.