diff --git a/litellm/caching/dual_cache.py b/litellm/caching/dual_cache.py index 4359898dee1..7e95eef22ba 100644 --- a/litellm/caching/dual_cache.py +++ b/litellm/caching/dual_cache.py @@ -561,7 +561,10 @@ class DualCache(BaseCache): effective_ttl: Final = self.default_in_memory_ttl if ttl is None else ttl if self.in_memory_cache is not None: await self.in_memory_cache.async_set_cache(key, value, ttl=effective_ttl) - return batch.set(key, value, effective_ttl) + redis_ttl = self.default_redis_ttl if ttl is None else ttl + if redis_ttl is None: + redis_ttl = effective_ttl + return batch.set(key, value, redis_ttl) # async_batch_set_cache async def async_set_cache_pipeline( diff --git a/tests/unit/caching/test_request_redis_batch_post_call.py b/tests/unit/caching/test_request_redis_batch_post_call.py index 2b5d3b3dbbb..07fc63e518d 100644 --- a/tests/unit/caching/test_request_redis_batch_post_call.py +++ b/tests/unit/caching/test_request_redis_batch_post_call.py @@ -295,6 +295,27 @@ async def test_a_deferred_response_cache_set_without_a_ttl_expires_in_redis_like assert command[3] == 300 +@pytest.mark.asyncio +async def test_a_deferred_response_cache_set_without_a_ttl_uses_default_redis_ttl_when_configured(): + client = FakeClient(_ok_replies) + redis_cache = PostCallFakeRedisCache(client) + dual_cache = DualCache( + redis_cache=redis_cache, + in_memory_cache=InMemoryCache(), + default_in_memory_ttl=300, + default_redis_ttl=3600, + ) + + await dual_cache.async_set_cache("direct", {"id": "resp"}) + with request_redis_batch_scope(): + await dual_cache.async_set_cache_post_call("deferred", {"id": "resp"}, None) + await flush_post_call_redis_batches() + + (command,) = client.pipelines[0].commands + assert (command[0], command[1], command[3]) == ("SET", "deferred", redis_cache.alone[0][2]["ttl"]) + assert command[3] == 3600 + + @pytest.mark.asyncio async def test_a_released_slot_is_free_locally_at_once_and_the_older_redis_count_does_not_overwrite_the_gauge(): def replies(command: tuple[object, ...]) -> object: