diff --git a/src/database.rs b/src/database.rs
index 0bf2a440..e66ff04d 100644
--- a/src/database.rs
+++ b/src/database.rs
@@ -278,6 +278,7 @@ impl Database {
                 pdu_cache: Mutex::new(LruCache::new(100_000)),
                 auth_chain_cache: Mutex::new(LruCache::new(100_000)),
                 shorteventid_cache: Mutex::new(LruCache::new(1_000_000)),
+                stateinfo_cache: Mutex::new(LruCache::new(1000)),
             },
             account_data: account_data::AccountData {
                 roomuserdataid_accountdata: builder.open_tree("roomuserdataid_accountdata")?,
diff --git a/src/database/rooms.rs b/src/database/rooms.rs
index 2832cc2d..5baadf9e 100644
--- a/src/database/rooms.rs
+++ b/src/database/rooms.rs
@@ -92,6 +92,13 @@ pub struct Rooms {
     pub(super) pdu_cache: Mutex<LruCache<EventId, Arc<PduEvent>>>,
     pub(super) auth_chain_cache: Mutex<LruCache<u64, HashSet<u64>>>,
     pub(super) shorteventid_cache: Mutex<LruCache<u64, EventId>>,
+    pub(super) stateinfo_cache: Mutex<LruCache<u64, 
+        Vec<(
+            u64,                           // sstatehash
+            HashSet<CompressedStateEvent>, // full state
+            HashSet<CompressedStateEvent>, // added
+            HashSet<CompressedStateEvent>, // removed
+        )>>>,
 }
 
 impl Rooms {
@@ -407,6 +414,14 @@ impl Rooms {
             HashSet<CompressedStateEvent>, // removed
         )>,
     > {
+        if let Some(r) = self.stateinfo_cache
+            .lock()
+            .unwrap()
+            .get_mut(&shortstatehash)
+        {
+            return Ok(r.clone());
+        }
+
         let value = self
             .shortstatehash_statediff
             .get(&shortstatehash.to_be_bytes())?
@@ -443,10 +458,18 @@ impl Rooms {
 
             response.push((shortstatehash, state, added, removed));
 
+            self.stateinfo_cache
+                .lock()
+                .unwrap()
+                .insert(shortstatehash, response.clone());
             Ok(response)
         } else {
             let mut response = Vec::new();
             response.push((shortstatehash, added.clone(), added, removed));
+            self.stateinfo_cache
+                .lock()
+                .unwrap()
+                .insert(shortstatehash, response.clone());
             Ok(response)
         }
     }