From 5ceaddd0b9f3fd0e5be83f453c8bddae0868ac82 Mon Sep 17 00:00:00 2001 From: "moyai-berriai[bot]" <336287033+moyai-berriai[bot]@users.noreply.github.com> Date: Tue, 20 Oct 2026 15:07:31 +0000 Subject: [PATCH] fix(cache): enforce byte-size limits for cached strings --- litellm/caching/in_memory_cache.py | 5 ++--- tests/unit/caching/test_in_memory_cache.py | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/litellm/caching/in_memory_cache.py b/litellm/caching/in_memory_cache.py index cb6426f64ff..a9af7237141 100644 --- a/litellm/caching/in_memory_cache.py +++ b/litellm/caching/in_memory_cache.py @@ -62,13 +62,12 @@ class InMemoryCache(BaseCache): try: # Fast path for common primitive types that are typically small if ( - isinstance(value, (bool, int, float, str)) + isinstance(value, (bool, int, float)) and len(str(value)) < self.max_size_per_item * MAX_SIZE_PER_ITEM_IN_MEMORY_CACHE_IN_KB ): # Conservative estimate return True - # Direct size check for bytes objects - if isinstance(value, bytes): + if isinstance(value, (str, bytes)): return sys.getsizeof(value) / 1024 <= self.max_size_per_item # Handle special types without full conversion when possible diff --git a/tests/unit/caching/test_in_memory_cache.py b/tests/unit/caching/test_in_memory_cache.py index 214f4ecf301..48d9229499c 100644 --- a/tests/unit/caching/test_in_memory_cache.py +++ b/tests/unit/caching/test_in_memory_cache.py @@ -76,6 +76,28 @@ def test_in_memory_cache_max_size_per_item(): assert result is False +@pytest.mark.parametrize( + ("character", "count", "should_cache"), + [ + ("a", 100, True), + ("\u00e9", 100, True), + ("\u6f22", 100, True), + ("\U0001f600", 100, True), + ("a", 1023, False), + ("\u00e9", 1023, False), + ("\u6f22", 600, False), + ("\U0001f600", 300, False), + ], +) +def test_string_cache_admission_respects_byte_size(character: str, count: int, should_cache: bool) -> None: + cache: Final = InMemoryCache(max_size_per_item=1, clock=lambda: 1000.0) + value: Final = character * count + + cache.set_cache("text", value) + + assert cache.get_cache("text") == (value if should_cache else None) + + def test_in_memory_cache_ttl(): """ Check that