diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/syncables/ClientBacklogManager.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/syncables/ClientBacklogManager.kt
index 633c45c8dfdfeeaaf6068683e3065ec32dcf26ad..9bb894a681c1953015eb03e580d0008c07af06fe 100644
--- a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/syncables/ClientBacklogManager.kt
+++ b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/syncables/ClientBacklogManager.kt
@@ -27,6 +27,7 @@ class ClientBacklogManager(
 ) : BacklogManager(session) {
   private val bufferQueue = CoroutineKeyedQueue<BacklogData.Buffer, QVariantList>()
   private val bufferFilteredQueue = CoroutineKeyedQueue<BacklogData.BufferFiltered, QVariantList>()
+  private val bufferForwardQueue = CoroutineKeyedQueue<BacklogData.BufferForward, QVariantList>()
   private val allQueue = CoroutineKeyedQueue<BacklogData.All, QVariantList>()
   private val allFilteredQueue = CoroutineKeyedQueue<BacklogData.AllFiltered, QVariantList>()
 
@@ -54,6 +55,18 @@ class ClientBacklogManager(
     return bufferFilteredQueue.wait(BacklogData.BufferFiltered(bufferId, first, last, limit, additional, type, flags))
   }
 
+  suspend fun backlogForward(
+    bufferId: BufferId,
+    first: MsgId = MsgId(-1),
+    last: MsgId = MsgId(-1),
+    limit: Int = -1,
+    type: MessageTypes = MessageType.all,
+    flags: MessageFlags = MessageFlag.all
+  ): QVariantList {
+    requestBacklogForward(bufferId, first, last, limit, type.toBits().toInt(), flags.toBits().toInt())
+    return bufferForwardQueue.wait(BacklogData.BufferForward(bufferId, first, last, limit, type, flags))
+  }
+
   suspend fun backlogAll(
     first: MsgId = MsgId(-1),
     last: MsgId = MsgId(-1),
@@ -177,6 +190,15 @@ class ClientBacklogManager(
       val flags: MessageFlags = MessageFlag.all
     ) : BacklogData()
 
+    data class BufferForward(
+      val bufferId: BufferId,
+      val first: MsgId = MsgId(-1),
+      val last: MsgId = MsgId(-1),
+      val limit: Int = -1,
+      val type: MessageTypes = MessageType.all,
+      val flags: MessageFlags = MessageFlag.all
+    ) : BacklogData()
+
     data class All(
       val first: MsgId = MsgId(-1),
       val last: MsgId = MsgId(-1),
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/features/QuasselFeature.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/features/QuasselFeature.kt
index 7593df14daf650ee98096ecbd47e2c58846bd4fa..1d23f49194be33a2d4e14002f0c1ad3ff0c8ee5b 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/features/QuasselFeature.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/features/QuasselFeature.kt
@@ -130,7 +130,17 @@ enum class QuasselFeature {
   /**
    * Support for dynamically updated core information
    */
-  SyncedCoreInfo;
+  SyncedCoreInfo,
+
+  /**
+   * Support for loading backlog in ascending order, old to new
+   */
+  LoadBacklogForwards,
+
+  /**
+   * Support for controlling what IRCv3 capabilities are skipped during negotiation
+   */
+  SkipIrcCaps;
 
   /**
    * Get the standardized feature name
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BacklogManagerStub.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BacklogManagerStub.kt
index c89f7b78e4fb031aa0818e447c4c257fbab7bc9d..694ebd574247e0d56e39ed566f1a5b09a2db21f2 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BacklogManagerStub.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BacklogManagerStub.kt
@@ -64,6 +64,27 @@ interface BacklogManagerStub : SyncableStub {
     )
   }
 
+  @SyncedCall(target = ProtocolSide.CORE)
+  fun requestBacklogForward(
+    bufferId: BufferId,
+    first: MsgId = MsgId(-1),
+    last: MsgId = MsgId(-1),
+    limit: Int = -1,
+    type: Int = -1,
+    flags: Int = -1
+  ) {
+    sync(
+      target = ProtocolSide.CORE,
+      "requestBacklogForward",
+      qVariant(bufferId, QuasselType.BufferId),
+      qVariant(first, QuasselType.MsgId),
+      qVariant(last, QuasselType.MsgId),
+      qVariant(limit, QtType.Int),
+      qVariant(type, QtType.Int),
+      qVariant(flags, QtType.Int),
+    )
+  }
+
   @SyncedCall(target = ProtocolSide.CORE)
   fun requestBacklogAll(
     first: MsgId = MsgId(-1),
@@ -148,6 +169,29 @@ interface BacklogManagerStub : SyncableStub {
     )
   }
 
+  @SyncedCall(target = ProtocolSide.CLIENT)
+  fun receiveBacklogForward(
+    bufferId: BufferId,
+    first: MsgId = MsgId(-1),
+    last: MsgId = MsgId(-1),
+    limit: Int = -1,
+    type: Int = -1,
+    flags: Int = -1,
+    messages: QVariantList
+  ) {
+    sync(
+      target = ProtocolSide.CLIENT,
+      "receiveBacklogForward",
+      qVariant(bufferId, QuasselType.BufferId),
+      qVariant(first, QuasselType.MsgId),
+      qVariant(last, QuasselType.MsgId),
+      qVariant(limit, QtType.Int),
+      qVariant(type, QtType.Int),
+      qVariant(flags, QtType.Int),
+      qVariant(messages, QtType.QVariantList),
+    )
+  }
+
   @SyncedCall(target = ProtocolSide.CLIENT)
   fun receiveBacklogAll(
     first: MsgId = MsgId(-1),