diff --git a/cache.go b/cache.go
index 3f2bd2d..0d86629 100644
--- a/cache.go
+++ b/cache.go
@@ -513,6 +513,32 @@ func (c *Cache[K, V]) Range(fn func(item *Item[K, V]) bool) {
 	}
 }
 
+// RangeBackwards calls fn for each unexpired item in the cache in reverse order.
+// If fn returns false, RangeBackwards stops the iteration.
+func (c *Cache[K, V]) RangeBackwards(fn func(item *Item[K, V]) bool) {
+	c.items.mu.RLock()
+
+	// Check if cache is empty
+	if c.items.lru.Len() == 0 {
+		c.items.mu.RUnlock()
+		return
+	}
+
+	for item := c.items.lru.Back(); item != c.items.lru.Front().Prev(); item = item.Prev() {
+		i := item.Value.(*Item[K, V])
+		expired := i.isExpiredUnsafe()
+		c.items.mu.RUnlock()
+
+		if !expired && !fn(i) {
+			return
+		}
+
+		if item.Prev() != nil {
+			c.items.mu.RLock()
+		}
+	}
+}
+
 // Metrics returns the metrics of the cache.
 func (c *Cache[K, V]) Metrics() Metrics {
 	c.metricsMu.RLock()
diff --git a/cache_test.go b/cache_test.go
index ac7db42..8020afc 100644
--- a/cache_test.go
+++ b/cache_test.go
@@ -329,18 +329,18 @@ func Test_Cache_set(t *testing.T) {
 	// recreate situation when expired item gets updated
 	// and not auto-cleaned up yet.
 	c := New[string, struct{}](
-		WithDisableTouchOnHit[string,struct{}](),
+		WithDisableTouchOnHit[string, struct{}](),
 	)
 
 	// insert an item and let it expire
 	c.Set("test", struct{}{}, 1)
-	time.Sleep(50*time.Millisecond)
+	time.Sleep(50 * time.Millisecond)
 
 	// update the expired item
 	updatedItem := c.Set("test", struct{}{}, 100*time.Millisecond)
 
 	// eviction should not happen as we prolonged element
-	cl := c.OnEviction(func(_ context.Context, _ EvictionReason, item *Item[string, struct{}]){
+	cl := c.OnEviction(func(_ context.Context, _ EvictionReason, item *Item[string, struct{}]) {
 		t.Errorf("eviction happened even though item has not expired yet: key=%s, evicted item expiresAt=%s, updated item expiresAt=%s, now=%s",
 			item.Key(),
 			item.ExpiresAt().String(),
@@ -351,7 +351,7 @@ func Test_Cache_set(t *testing.T) {
 	// and update expired before its removal
 	go c.Start()
 
-	time.Sleep(90*time.Millisecond)
+	time.Sleep(90 * time.Millisecond)
 	cl()
 	c.Stop()
 }
@@ -848,6 +848,28 @@ func Test_Cache_Range(t *testing.T) {
 	})
 }
 
+func Test_Cache_RangeBackwards(t *testing.T) {
+	c := prepCache(DefaultTTL)
+	addToCache(c, time.Nanosecond, "1")
+	addToCache(c, time.Hour, "2", "3", "4", "5")
+
+	var results []string
+
+	c.RangeBackwards(func(item *Item[string, string]) bool {
+		results = append(results, item.Key())
+		return item.Key() != "4"
+	})
+
+	assert.Equal(t, []string{"2", "3", "4"}, results)
+
+	emptyCache := New[string, string]()
+	assert.NotPanics(t, func() {
+		emptyCache.RangeBackwards(func(item *Item[string, string]) bool {
+			return false
+		})
+	})
+}
+
 func Test_Cache_Metrics(t *testing.T) {
 	cache := Cache[string, string]{
 		metrics: Metrics{Evictions: 10},