diff --git a/src/database.rs b/src/database.rs
index 0bf2a44075007db18c905bba8a82d86c4abee0e2..e66ff04d2c4434bdf161973c5b2b4af4fc21cebd 100644
--- a/src/database.rs
+++ b/src/database.rs
@@ -278,6 +278,7 @@ pub async fn load_or_create(config: &Config) -> Result<Arc<TokioRwLock<Self>>> {
                 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 2832cc2d8a017948ef60e1ebb37e91cfe30e64f9..5baadf9e7236326eeb438f0e6d545c31b905ac42 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 @@ pub fn load_shortstatehash_info(
             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 @@ pub fn load_shortstatehash_info(
 
             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)
         }
     }