diff --git a/src/plugins/sib-history-improved.js b/src/plugins/sib-history-improved.js
new file mode 100644
index 0000000000000000000000000000000000000000..f09ff47686c01f080005f2381c35372c611efa67
--- /dev/null
+++ b/src/plugins/sib-history-improved.js
@@ -0,0 +1,86 @@
+/**
+ * Updates the history behavior of chat boxes.
+ */
+converse.plugins.add('sib-history-improved', {
+  dependencies: [
+    'converse-mam',
+  ],
+  overrides: {
+    ChatRoomView: {
+      events: {
+        'wheel .chat-content__messages': 'onScrolledUp',
+      },
+    },
+    ChatBoxView: {
+      events: {
+        'wheel .chat-content__messages': 'onScrolledUp',
+      },
+
+      /**
+       * Fetch the old messages if there is no scroll available.
+       * @param {WheelEvent} ev
+       */
+      onScrolledUp(ev) {
+        const { api } = this.__super__._converse;
+        const { utils } = converse.env;
+        const scrollable = this.msgs_container.clientHeight < this.msgs_container.scrollHeight;
+
+        if (ev.deltaY < 0 && !scrollable) {
+          api.trigger('chatBoxScrolledUp', this);
+          utils.safeSave(this.model, {
+            scrolled: true,
+            scrollTop: 0,
+          });
+        }
+      },
+    },
+  },
+  initialize() {
+    const _converse = this._converse;
+    const { api } = _converse;
+    const { log } = converse.env;
+    let counter = 0;
+
+    // Forces the loading of the real number of messages (or more)
+    // from the setting `archived_messages_page_size`.
+    api.listen.on('MAMResult', async data => {
+
+      const max = +api.settings.get('archived_messages_page_size');
+      const messages = await Promise.all(data.messages);
+
+      // Increase counter with the messages that contains a body
+      counter += messages.filter(attrs => attrs.body).length;
+
+      // Stop if the max value is not specified
+      // Stop if there are less messages available than the page size
+      // Stop if the counter registers more messages than the max value
+      if (!max || messages.length < max || counter >= max) {
+        log.debug(`Chatbox has enough messages or cannot get more, count: ${counter}`);
+        counter = 0;
+        return;
+      }
+
+      log.debug(`Chatbox needs more messages, count: ${counter}`);
+
+      const is_groupchat = data.chatbox.get('type') === converse.CHATROOMS_TYPE;
+      const oldest_message = messages.pop();
+
+      if (oldest_message) {
+        const by_jid = is_groupchat ? data.chatbox.get('jid') : _converse.bare_jid;
+        const stanza_id = oldest_message && oldest_message['stanza_id '.concat(by_jid)];
+
+        if (stanza_id) {
+          log.debug(`Loading messages before stanza: ${stanza_id}`);
+          await data.chatbox.fetchArchivedMessages({
+            'before': stanza_id,
+          });
+        } else {
+          log.debug(`Loading messages before time: ${oldest_message['time']}`);
+          await data.chatbox.fetchArchivedMessages({
+            'end': oldest_message['time'],
+          });
+        }
+      }
+    });
+  },
+});
diff --git a/src/plugins/sib-mam-history.js b/src/plugins/sib-mam-history.js
deleted file mode 100644
index f0704e759212129dce7970a2196b940b0443e8d6..0000000000000000000000000000000000000000
--- a/src/plugins/sib-mam-history.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * Forces the loading of the real number of messages (or more)
- * from the setting `archived_messages_page_size`.
- */
-converse.plugins.add('sib-mam-history', {
-  dependencies: [
-    'converse-mam',
-  ],
-  initialize() {
-    const { api } = this._converse;
-    let counter = 0;
-
-    api.listen.on('MAMResult', async data => {
-
-      const max = +api.settings.get('archived_messages_page_size');
-      const messages = await Promise.all(data.messages);
-
-      // Increase counter with the messages that contains a body
-      counter += messages.filter(attrs => attrs.body).length;
-
-      // Stop if the max value is not specified
-      // Stop if there are less messages available than the page size
-      // Stop if the counter registers more messages than the max value
-      if (!max || messages.length < max || counter >= max) {
-        counter = 0;
-        return;
-      }
-
-      const is_groupchat = data.chatbox.get('type') === converse.CHATROOMS_TYPE;
-      const oldest_message = messages.pop();
-
-      if (oldest_message) {
-        const by_jid = is_groupchat ? data.chatbox.get('jid') : converse.bare_jid;
-        const stanza_id = oldest_message && oldest_message['stanza_id '.concat(by_jid)];
-
-        if (stanza_id) {
-          await data.chatbox.fetchArchivedMessages({
-            'before': stanza_id,
-          });
-        } else {
-          await data.chatbox.fetchArchivedMessages({
-            'end': oldest_message['time'],
-          });
-        }
-      }
-    });
-  },
-});
diff --git a/src/solid-xmpp-chat.js b/src/solid-xmpp-chat.js
index 6f82a1636844f333f652c345a25b7c65ee31067d..e6c792da921f140a734b19e4bb29759d77cfa955 100644
--- a/src/solid-xmpp-chat.js
+++ b/src/solid-xmpp-chat.js
@@ -9,7 +9,7 @@ import './plugins/converse-rai.js';
 import './plugins/sib-chat-navigation.js';
 import './plugins/sib-custom-hats.js';
 import './plugins/sib-disconnected.js';
-import './plugins/sib-mam-history.js';
+import './plugins/sib-history-improved.js';
 import './plugins/sib-mention-mobile.js';
 import './plugins/sib-remove-notifications.js';
 import './plugins/sib-reply-to-message.js';
@@ -226,7 +226,7 @@ export const SolidXMPPChat = {
           'sib-connected',
           'sib-custom-hats',
           'sib-disconnected',
-          'sib-mam-history',
+          'sib-history-improved',
           'sib-mention-mobile',
           'sib-remove-notifications',
           'sib-reply-to-message',