diff --git a/src/components/views/rooms/RoomSublist.tsx b/src/components/views/rooms/RoomSublist.tsx
index fce9e297a1..8d825a2b53 100644
--- a/src/components/views/rooms/RoomSublist.tsx
+++ b/src/components/views/rooms/RoomSublist.tsx
@@ -408,10 +408,10 @@ export default class RoomSublist extends React.Component<IProps, IState> {
         this.setState({ addRoomContextMenuPosition: null });
     };
 
-    private onUnreadFirstChanged = async () => {
+    private onUnreadFirstChanged = () => {
         const isUnreadFirst = RoomListStore.instance.getListOrder(this.props.tagId) === ListAlgorithm.Importance;
         const newAlgorithm = isUnreadFirst ? ListAlgorithm.Natural : ListAlgorithm.Importance;
-        await RoomListStore.instance.setListOrder(this.props.tagId, newAlgorithm);
+        RoomListStore.instance.setListOrder(this.props.tagId, newAlgorithm);
         this.forceUpdate(); // because if the sublist doesn't have any changes then we will miss the list order change
     };
 
diff --git a/src/stores/room-list/RoomListStore.ts b/src/stores/room-list/RoomListStore.ts
index bedbfebd7f..3913a2220f 100644
--- a/src/stores/room-list/RoomListStore.ts
+++ b/src/stores/room-list/RoomListStore.ts
@@ -132,8 +132,8 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
         // Update any settings here, as some may have happened before we were logically ready.
         console.log("Regenerating room lists: Startup");
         await this.readAndCacheSettingsFromStore();
-        await this.regenerateAllLists({ trigger: false });
-        await this.handleRVSUpdate({ trigger: false }); // fake an RVS update to adjust sticky room, if needed
+        this.regenerateAllLists({ trigger: false });
+        this.handleRVSUpdate({ trigger: false }); // fake an RVS update to adjust sticky room, if needed
 
         this.updateFn.mark(); // we almost certainly want to trigger an update.
         this.updateFn.trigger();
@@ -150,7 +150,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
         await this.updateState({
             tagsEnabled,
         });
-        await this.updateAlgorithmInstances();
+        this.updateAlgorithmInstances();
     }
 
     /**
@@ -158,23 +158,23 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
      * @param trigger Set to false to prevent a list update from being sent. Should only
      * be used if the calling code will manually trigger the update.
      */
-    private async handleRVSUpdate({ trigger = true }) {
+    private handleRVSUpdate({ trigger = true }) {
         if (!this.matrixClient) return; // We assume there won't be RVS updates without a client
 
         const activeRoomId = RoomViewStore.getRoomId();
         if (!activeRoomId && this.algorithm.stickyRoom) {
-            await this.algorithm.setStickyRoom(null);
+            this.algorithm.setStickyRoom(null);
         } else if (activeRoomId) {
             const activeRoom = this.matrixClient.getRoom(activeRoomId);
             if (!activeRoom) {
                 console.warn(`${activeRoomId} is current in RVS but missing from client - clearing sticky room`);
-                await this.algorithm.setStickyRoom(null);
+                this.algorithm.setStickyRoom(null);
             } else if (activeRoom !== this.algorithm.stickyRoom) {
                 if (SettingsStore.getValue("advancedRoomListLogging")) {
                     // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
                     console.log(`Changing sticky room to ${activeRoomId}`);
                 }
-                await this.algorithm.setStickyRoom(activeRoom);
+                this.algorithm.setStickyRoom(activeRoom);
             }
         }
 
@@ -226,7 +226,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
                 console.log("Regenerating room lists: Settings changed");
                 await this.readAndCacheSettingsFromStore();
 
-                await this.regenerateAllLists({ trigger: false }); // regenerate the lists now
+                this.regenerateAllLists({ trigger: false }); // regenerate the lists now
                 this.updateFn.trigger();
             }
         }
@@ -368,7 +368,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
                                 // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
                                 console.log(`[RoomListDebug] Clearing sticky room due to room upgrade`);
                             }
-                            await this.algorithm.setStickyRoom(null);
+                            this.algorithm.setStickyRoom(null);
                         }
 
                         // Note: we hit the algorithm instead of our handleRoomUpdate() function to
@@ -377,7 +377,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
                             // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
                             console.log(`[RoomListDebug] Removing previous room from room list`);
                         }
-                        await this.algorithm.handleRoomUpdate(prevRoom, RoomUpdateCause.RoomRemoved);
+                        this.algorithm.handleRoomUpdate(prevRoom, RoomUpdateCause.RoomRemoved);
                     }
                 }
 
@@ -433,7 +433,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
             return; // don't do anything on new/moved rooms which ought not to be shown
         }
 
-        const shouldUpdate = await this.algorithm.handleRoomUpdate(room, cause);
+        const shouldUpdate = this.algorithm.handleRoomUpdate(room, cause);
         if (shouldUpdate) {
             if (SettingsStore.getValue("advancedRoomListLogging")) {
                 // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
@@ -462,13 +462,13 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
 
         // Reset the sticky room before resetting the known rooms so the algorithm
         // doesn't freak out.
-        await this.algorithm.setStickyRoom(null);
-        await this.algorithm.setKnownRooms(rooms);
+        this.algorithm.setStickyRoom(null);
+        this.algorithm.setKnownRooms(rooms);
 
         // Set the sticky room back, if needed, now that we have updated the store.
         // This will use relative stickyness to the new room set.
         if (stickyIsStillPresent) {
-            await this.algorithm.setStickyRoom(currentSticky);
+            this.algorithm.setStickyRoom(currentSticky);
         }
 
         // Finally, mark an update and resume updates from the algorithm
@@ -477,12 +477,12 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
     }
 
     public async setTagSorting(tagId: TagID, sort: SortAlgorithm) {
-        await this.setAndPersistTagSorting(tagId, sort);
+        this.setAndPersistTagSorting(tagId, sort);
         this.updateFn.trigger();
     }
 
-    private async setAndPersistTagSorting(tagId: TagID, sort: SortAlgorithm) {
-        await this.algorithm.setTagSorting(tagId, sort);
+    private setAndPersistTagSorting(tagId: TagID, sort: SortAlgorithm) {
+        this.algorithm.setTagSorting(tagId, sort);
         // TODO: Per-account? https://github.com/vector-im/element-web/issues/14114
         localStorage.setItem(`mx_tagSort_${tagId}`, sort);
     }
@@ -520,13 +520,13 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
         return tagSort;
     }
 
-    public async setListOrder(tagId: TagID, order: ListAlgorithm) {
-        await this.setAndPersistListOrder(tagId, order);
+    public setListOrder(tagId: TagID, order: ListAlgorithm) {
+        this.setAndPersistListOrder(tagId, order);
         this.updateFn.trigger();
     }
 
-    private async setAndPersistListOrder(tagId: TagID, order: ListAlgorithm) {
-        await this.algorithm.setListOrdering(tagId, order);
+    private setAndPersistListOrder(tagId: TagID, order: ListAlgorithm) {
+        this.algorithm.setListOrdering(tagId, order);
         // TODO: Per-account? https://github.com/vector-im/element-web/issues/14114
         localStorage.setItem(`mx_listOrder_${tagId}`, order);
     }
@@ -563,7 +563,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
         return listOrder;
     }
 
-    private async updateAlgorithmInstances() {
+    private updateAlgorithmInstances() {
         // We'll require an update, so mark for one. Marking now also prevents the calls
         // to setTagSorting and setListOrder from causing triggers.
         this.updateFn.mark();
@@ -576,10 +576,10 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
             const listOrder = this.calculateListOrder(tag);
 
             if (tagSort !== definedSort) {
-                await this.setAndPersistTagSorting(tag, tagSort);
+                this.setAndPersistTagSorting(tag, tagSort);
             }
             if (listOrder !== definedOrder) {
-                await this.setAndPersistListOrder(tag, listOrder);
+                this.setAndPersistListOrder(tag, listOrder);
             }
         }
     }
@@ -632,7 +632,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
      * @param trigger Set to false to prevent a list update from being sent. Should only
      * be used if the calling code will manually trigger the update.
      */
-    public async regenerateAllLists({ trigger = true }) {
+    public regenerateAllLists({ trigger = true }) {
         console.warn("Regenerating all room lists");
 
         const rooms = this.getPlausibleRooms();
@@ -656,8 +656,8 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
             RoomListLayoutStore.instance.ensureLayoutExists(tagId);
         }
 
-        await this.algorithm.populateTags(sorts, orders);
-        await this.algorithm.setKnownRooms(rooms);
+        this.algorithm.populateTags(sorts, orders);
+        this.algorithm.setKnownRooms(rooms);
 
         this.initialListsGenerated = true;
 
diff --git a/src/stores/room-list/algorithms/Algorithm.ts b/src/stores/room-list/algorithms/Algorithm.ts
index 2acce1ecd7..8574f095d6 100644
--- a/src/stores/room-list/algorithms/Algorithm.ts
+++ b/src/stores/room-list/algorithms/Algorithm.ts
@@ -17,7 +17,6 @@ limitations under the License.
 import { Room } from "matrix-js-sdk/src/models/room";
 import { isNullOrUndefined } from "matrix-js-sdk/src/utils";
 import { EventEmitter } from "events";
-import AwaitLock from "await-lock";
 
 import DMRoomMap from "../../../utils/DMRoomMap";
 import { arrayDiff, arrayHasDiff } from "../../../utils/arrays";
@@ -80,7 +79,6 @@ export class Algorithm extends EventEmitter {
     } = {};
     private allowedByFilter: Map<IFilterCondition, Room[]> = new Map<IFilterCondition, Room[]>();
     private allowedRoomsByFilters: Set<Room> = new Set<Room>();
-    private stickyLock = new AwaitLock();
 
     /**
      * Set to true to suspend emissions of algorithm updates.
@@ -125,13 +123,8 @@ export class Algorithm extends EventEmitter {
      * Awaitable version of the sticky room setter.
      * @param val The new room to sticky.
      */
-    public async setStickyRoom(val: Room) {
-        await this.stickyLock.acquireAsync();
-        try {
-            await this.updateStickyRoom(val);
-        } finally {
-            this.stickyLock.release();
-        }
+    public setStickyRoom(val: Room) {
+        this.updateStickyRoom(val);
     }
 
     public getTagSorting(tagId: TagID): SortAlgorithm {
@@ -139,13 +132,13 @@ export class Algorithm extends EventEmitter {
         return this.sortAlgorithms[tagId];
     }
 
-    public async setTagSorting(tagId: TagID, sort: SortAlgorithm) {
+    public setTagSorting(tagId: TagID, sort: SortAlgorithm) {
         if (!tagId) throw new Error("Tag ID must be defined");
         if (!sort) throw new Error("Algorithm must be defined");
         this.sortAlgorithms[tagId] = sort;
 
         const algorithm: OrderingAlgorithm = this.algorithms[tagId];
-        await algorithm.setSortAlgorithm(sort);
+        algorithm.setSortAlgorithm(sort);
         this._cachedRooms[tagId] = algorithm.orderedRooms;
         this.recalculateFilteredRoomsForTag(tagId); // update filter to re-sort the list
         this.recalculateStickyRoom(tagId); // update sticky room to make sure it appears if needed
@@ -156,7 +149,7 @@ export class Algorithm extends EventEmitter {
         return this.listAlgorithms[tagId];
     }
 
-    public async setListOrdering(tagId: TagID, order: ListAlgorithm) {
+    public setListOrdering(tagId: TagID, order: ListAlgorithm) {
         if (!tagId) throw new Error("Tag ID must be defined");
         if (!order) throw new Error("Algorithm must be defined");
         this.listAlgorithms[tagId] = order;
@@ -164,7 +157,7 @@ export class Algorithm extends EventEmitter {
         const algorithm = getListAlgorithmInstance(order, tagId, this.sortAlgorithms[tagId]);
         this.algorithms[tagId] = algorithm;
 
-        await algorithm.setRooms(this._cachedRooms[tagId]);
+        algorithm.setRooms(this._cachedRooms[tagId]);
         this._cachedRooms[tagId] = algorithm.orderedRooms;
         this.recalculateFilteredRoomsForTag(tagId); // update filter to re-sort the list
         this.recalculateStickyRoom(tagId); // update sticky room to make sure it appears if needed
@@ -191,31 +184,25 @@ export class Algorithm extends EventEmitter {
         }
     }
 
-    private async handleFilterChange() {
-        await this.recalculateFilteredRooms();
+    private handleFilterChange() {
+        this.recalculateFilteredRooms();
 
         // re-emit the update so the list store can fire an off-cycle update if needed
         if (this.updatesInhibited) return;
         this.emit(FILTER_CHANGED);
     }
 
-    private async updateStickyRoom(val: Room) {
-        try {
-            return await this.doUpdateStickyRoom(val);
-        } finally {
-            this._lastStickyRoom = null; // clear to indicate we're done changing
-        }
+    private updateStickyRoom(val: Room) {
+        this.doUpdateStickyRoom(val);
+        this._lastStickyRoom = null; // clear to indicate we're done changing
     }
 
-    private async doUpdateStickyRoom(val: Room) {
+    private doUpdateStickyRoom(val: Room) {
         if (SpaceStore.spacesEnabled && val?.isSpaceRoom() && val.getMyMembership() !== "invite") {
             // no-op sticky rooms for spaces - they're effectively virtual rooms
             val = null;
         }
 
-        // Note throughout: We need async so we can wait for handleRoomUpdate() to do its thing,
-        // otherwise we risk duplicating rooms.
-
         if (val && !VisibilityProvider.instance.isRoomVisible(val)) {
             val = null; // the room isn't visible - lie to the rest of this function
         }
@@ -231,7 +218,7 @@ export class Algorithm extends EventEmitter {
                 this._stickyRoom = null; // clear before we go to update the algorithm
 
                 // Lie to the algorithm and re-add the room to the algorithm
-                await this.handleRoomUpdate(stickyRoom, RoomUpdateCause.NewRoom);
+                this.handleRoomUpdate(stickyRoom, RoomUpdateCause.NewRoom);
                 return;
             }
             return;
@@ -277,10 +264,10 @@ export class Algorithm extends EventEmitter {
         // referential checks as the references can differ through the lifecycle.
         if (lastStickyRoom && lastStickyRoom.room && lastStickyRoom.room.roomId !== val.roomId) {
             // Lie to the algorithm and re-add the room to the algorithm
-            await this.handleRoomUpdate(lastStickyRoom.room, RoomUpdateCause.NewRoom);
+            this.handleRoomUpdate(lastStickyRoom.room, RoomUpdateCause.NewRoom);
         }
         // Lie to the algorithm and remove the room from it's field of view
-        await this.handleRoomUpdate(val, RoomUpdateCause.RoomRemoved);
+        this.handleRoomUpdate(val, RoomUpdateCause.RoomRemoved);
 
         // Check for tag & position changes while we're here. We also check the room to ensure
         // it is still the same room.
@@ -470,9 +457,8 @@ export class Algorithm extends EventEmitter {
      * them.
      * @param {ITagSortingMap} tagSortingMap The tags to generate.
      * @param {IListOrderingMap} listOrderingMap The ordering of those tags.
-     * @returns {Promise<*>} A promise which resolves when complete.
      */
-    public async populateTags(tagSortingMap: ITagSortingMap, listOrderingMap: IListOrderingMap): Promise<any> {
+    public populateTags(tagSortingMap: ITagSortingMap, listOrderingMap: IListOrderingMap): void {
         if (!tagSortingMap) throw new Error(`Sorting map cannot be null or empty`);
         if (!listOrderingMap) throw new Error(`Ordering ma cannot be null or empty`);
         if (arrayHasDiff(Object.keys(tagSortingMap), Object.keys(listOrderingMap))) {
@@ -521,93 +507,87 @@ export class Algorithm extends EventEmitter {
      * Seeds the Algorithm with a set of rooms. The algorithm will discard all
      * previously known information and instead use these rooms instead.
      * @param {Room[]} rooms The rooms to force the algorithm to use.
-     * @returns {Promise<*>} A promise which resolves when complete.
      */
-    public async setKnownRooms(rooms: Room[]): Promise<any> {
+    public setKnownRooms(rooms: Room[]): void {
         if (isNullOrUndefined(rooms)) throw new Error(`Array of rooms cannot be null`);
         if (!this.sortAlgorithms) throw new Error(`Cannot set known rooms without a tag sorting map`);
 
-        await this.stickyLock.acquireAsync();
-        try {
-            if (!this.updatesInhibited) {
-                // We only log this if we're expecting to be publishing updates, which means that
-                // this could be an unexpected invocation. If we're inhibited, then this is probably
-                // an intentional invocation.
-                console.warn("Resetting known rooms, initiating regeneration");
-            }
+        if (!this.updatesInhibited) {
+            // We only log this if we're expecting to be publishing updates, which means that
+            // this could be an unexpected invocation. If we're inhibited, then this is probably
+            // an intentional invocation.
+            console.warn("Resetting known rooms, initiating regeneration");
+        }
 
-            // Before we go any further we need to clear (but remember) the sticky room to
-            // avoid accidentally duplicating it in the list.
-            const oldStickyRoom = this._stickyRoom;
-            if (oldStickyRoom) await this.updateStickyRoom(null);
+        // Before we go any further we need to clear (but remember) the sticky room to
+        // avoid accidentally duplicating it in the list.
+        const oldStickyRoom = this._stickyRoom;
+        if (oldStickyRoom) this.updateStickyRoom(null);
 
-            this.rooms = rooms;
+        this.rooms = rooms;
 
-            const newTags: ITagMap = {};
-            for (const tagId in this.sortAlgorithms) {
-                // noinspection JSUnfilteredForInLoop
-                newTags[tagId] = [];
-            }
+        const newTags: ITagMap = {};
+        for (const tagId in this.sortAlgorithms) {
+            // noinspection JSUnfilteredForInLoop
+            newTags[tagId] = [];
+        }
 
-            // If we can avoid doing work, do so.
-            if (!rooms.length) {
-                await this.generateFreshTags(newTags); // just in case it wants to do something
-                this.cachedRooms = newTags;
-                return;
-            }
+        // If we can avoid doing work, do so.
+        if (!rooms.length) {
+            this.generateFreshTags(newTags); // just in case it wants to do something
+            this.cachedRooms = newTags;
+            return;
+        }
 
-            // Split out the easy rooms first (leave and invite)
-            const memberships = splitRoomsByMembership(rooms);
-            for (const room of memberships[EffectiveMembership.Invite]) {
-                newTags[DefaultTagID.Invite].push(room);
-            }
-            for (const room of memberships[EffectiveMembership.Leave]) {
-                newTags[DefaultTagID.Archived].push(room);
-            }
+        // Split out the easy rooms first (leave and invite)
+        const memberships = splitRoomsByMembership(rooms);
+        for (const room of memberships[EffectiveMembership.Invite]) {
+            newTags[DefaultTagID.Invite].push(room);
+        }
+        for (const room of memberships[EffectiveMembership.Leave]) {
+            newTags[DefaultTagID.Archived].push(room);
+        }
 
-            // Now process all the joined rooms. This is a bit more complicated
-            for (const room of memberships[EffectiveMembership.Join]) {
-                const tags = this.getTagsOfJoinedRoom(room);
+        // Now process all the joined rooms. This is a bit more complicated
+        for (const room of memberships[EffectiveMembership.Join]) {
+            const tags = this.getTagsOfJoinedRoom(room);
 
-                let inTag = false;
-                if (tags.length > 0) {
-                    for (const tag of tags) {
-                        if (!isNullOrUndefined(newTags[tag])) {
-                            newTags[tag].push(room);
-                            inTag = true;
-                        }
-                    }
-                }
-
-                if (!inTag) {
-                    if (DMRoomMap.shared().getUserIdForRoomId(room.roomId)) {
-                        newTags[DefaultTagID.DM].push(room);
-                    } else {
-                        newTags[DefaultTagID.Untagged].push(room);
+            let inTag = false;
+            if (tags.length > 0) {
+                for (const tag of tags) {
+                    if (!isNullOrUndefined(newTags[tag])) {
+                        newTags[tag].push(room);
+                        inTag = true;
                     }
                 }
             }
 
-            await this.generateFreshTags(newTags);
-
-            this.cachedRooms = newTags; // this recalculates the filtered rooms for us
-            this.updateTagsFromCache();
-
-            // Now that we've finished generation, we need to update the sticky room to what
-            // it was. It's entirely possible that it changed lists though, so if it did then
-            // we also have to update the position of it.
-            if (oldStickyRoom && oldStickyRoom.room) {
-                await this.updateStickyRoom(oldStickyRoom.room);
-                if (this._stickyRoom && this._stickyRoom.room) { // just in case the update doesn't go according to plan
-                    if (this._stickyRoom.tag !== oldStickyRoom.tag) {
-                        // We put the sticky room at the top of the list to treat it as an obvious tag change.
-                        this._stickyRoom.position = 0;
-                        this.recalculateStickyRoom(this._stickyRoom.tag);
-                    }
+            if (!inTag) {
+                if (DMRoomMap.shared().getUserIdForRoomId(room.roomId)) {
+                    newTags[DefaultTagID.DM].push(room);
+                } else {
+                    newTags[DefaultTagID.Untagged].push(room);
+                }
+            }
+        }
+
+        this.generateFreshTags(newTags);
+
+        this.cachedRooms = newTags; // this recalculates the filtered rooms for us
+        this.updateTagsFromCache();
+
+        // Now that we've finished generation, we need to update the sticky room to what
+        // it was. It's entirely possible that it changed lists though, so if it did then
+        // we also have to update the position of it.
+        if (oldStickyRoom && oldStickyRoom.room) {
+            this.updateStickyRoom(oldStickyRoom.room);
+            if (this._stickyRoom && this._stickyRoom.room) { // just in case the update doesn't go according to plan
+                if (this._stickyRoom.tag !== oldStickyRoom.tag) {
+                    // We put the sticky room at the top of the list to treat it as an obvious tag change.
+                    this._stickyRoom.position = 0;
+                    this.recalculateStickyRoom(this._stickyRoom.tag);
                 }
             }
-        } finally {
-            this.stickyLock.release();
         }
     }
 
@@ -665,16 +645,15 @@ export class Algorithm extends EventEmitter {
      * @param {ITagMap} updatedTagMap The tag map which needs populating. Each tag
      * will already have the rooms which belong to it - they just need ordering. Must
      * be mutated in place.
-     * @returns {Promise<*>} A promise which resolves when complete.
      */
-    private async generateFreshTags(updatedTagMap: ITagMap): Promise<any> {
+    private generateFreshTags(updatedTagMap: ITagMap): void {
         if (!this.algorithms) throw new Error("Not ready: no algorithms to determine tags from");
 
         for (const tag of Object.keys(updatedTagMap)) {
             const algorithm: OrderingAlgorithm = this.algorithms[tag];
             if (!algorithm) throw new Error(`No algorithm for ${tag}`);
 
-            await algorithm.setRooms(updatedTagMap[tag]);
+            algorithm.setRooms(updatedTagMap[tag]);
             updatedTagMap[tag] = algorithm.orderedRooms;
         }
     }
@@ -686,11 +665,10 @@ export class Algorithm extends EventEmitter {
      * may no-op this request if no changes are required.
      * @param {Room} room The room which might have affected sorting.
      * @param {RoomUpdateCause} cause The reason for the update being triggered.
-     * @returns {Promise<boolean>} A promise which resolve to true or false
-     * depending on whether or not getOrderedRooms() should be called after
-     * processing.
+     * @returns {Promise<boolean>} A boolean of whether or not getOrderedRooms()
+     * should be called after processing.
      */
-    public async handleRoomUpdate(room: Room, cause: RoomUpdateCause): Promise<boolean> {
+    public handleRoomUpdate(room: Room, cause: RoomUpdateCause): boolean {
         if (SettingsStore.getValue("advancedRoomListLogging")) {
             // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
             console.log(`Handle room update for ${room.roomId} called with cause ${cause}`);
@@ -757,7 +735,7 @@ export class Algorithm extends EventEmitter {
                     }
                     const algorithm: OrderingAlgorithm = this.algorithms[rmTag];
                     if (!algorithm) throw new Error(`No algorithm for ${rmTag}`);
-                    await algorithm.handleRoomUpdate(room, RoomUpdateCause.RoomRemoved);
+                    algorithm.handleRoomUpdate(room, RoomUpdateCause.RoomRemoved);
                     this._cachedRooms[rmTag] = algorithm.orderedRooms;
                     this.recalculateFilteredRoomsForTag(rmTag); // update filter to re-sort the list
                     this.recalculateStickyRoom(rmTag); // update sticky room to make sure it moves if needed
@@ -769,7 +747,7 @@ export class Algorithm extends EventEmitter {
                     }
                     const algorithm: OrderingAlgorithm = this.algorithms[addTag];
                     if (!algorithm) throw new Error(`No algorithm for ${addTag}`);
-                    await algorithm.handleRoomUpdate(room, RoomUpdateCause.NewRoom);
+                    algorithm.handleRoomUpdate(room, RoomUpdateCause.NewRoom);
                     this._cachedRooms[addTag] = algorithm.orderedRooms;
                 }
 
@@ -802,7 +780,7 @@ export class Algorithm extends EventEmitter {
                     };
                 } else {
                     // We have to clear the lock as the sticky room change will trigger updates.
-                    await this.setStickyRoom(room);
+                    this.setStickyRoom(room);
                 }
             }
         }
@@ -865,7 +843,7 @@ export class Algorithm extends EventEmitter {
             const algorithm: OrderingAlgorithm = this.algorithms[tag];
             if (!algorithm) throw new Error(`No algorithm for ${tag}`);
 
-            await algorithm.handleRoomUpdate(room, cause);
+            algorithm.handleRoomUpdate(room, cause);
             this._cachedRooms[tag] = algorithm.orderedRooms;
 
             // Flag that we've done something
diff --git a/src/stores/room-list/algorithms/list-ordering/ImportanceAlgorithm.ts b/src/stores/room-list/algorithms/list-ordering/ImportanceAlgorithm.ts
index 80bdf74afb..1d35df331d 100644
--- a/src/stores/room-list/algorithms/list-ordering/ImportanceAlgorithm.ts
+++ b/src/stores/room-list/algorithms/list-ordering/ImportanceAlgorithm.ts
@@ -94,15 +94,15 @@ export class ImportanceAlgorithm extends OrderingAlgorithm {
         return state.color;
     }
 
-    public async setRooms(rooms: Room[]): Promise<any> {
+    public setRooms(rooms: Room[]): void {
         if (this.sortingAlgorithm === SortAlgorithm.Manual) {
-            this.cachedOrderedRooms = await sortRoomsWithAlgorithm(rooms, this.tagId, this.sortingAlgorithm);
+            this.cachedOrderedRooms = sortRoomsWithAlgorithm(rooms, this.tagId, this.sortingAlgorithm);
         } else {
             // Every other sorting type affects the categories, not the whole tag.
             const categorized = this.categorizeRooms(rooms);
             for (const category of Object.keys(categorized)) {
                 const roomsToOrder = categorized[category];
-                categorized[category] = await sortRoomsWithAlgorithm(roomsToOrder, this.tagId, this.sortingAlgorithm);
+                categorized[category] = sortRoomsWithAlgorithm(roomsToOrder, this.tagId, this.sortingAlgorithm);
             }
 
             const newlyOrganized: Room[] = [];
@@ -118,12 +118,12 @@ export class ImportanceAlgorithm extends OrderingAlgorithm {
         }
     }
 
-    private async handleSplice(room: Room, cause: RoomUpdateCause): Promise<boolean> {
+    private handleSplice(room: Room, cause: RoomUpdateCause): boolean {
         if (cause === RoomUpdateCause.NewRoom) {
             const category = this.getRoomCategory(room);
             this.alterCategoryPositionBy(category, 1, this.indices);
             this.cachedOrderedRooms.splice(this.indices[category], 0, room); // splice in the new room (pre-adjusted)
-            await this.sortCategory(category);
+            this.sortCategory(category);
         } else if (cause === RoomUpdateCause.RoomRemoved) {
             const roomIdx = this.getRoomIndex(room);
             if (roomIdx === -1) {
@@ -141,55 +141,49 @@ export class ImportanceAlgorithm extends OrderingAlgorithm {
         return true;
     }
 
-    public async handleRoomUpdate(room: Room, cause: RoomUpdateCause): Promise<boolean> {
-        try {
-            await this.updateLock.acquireAsync();
-
-            if (cause === RoomUpdateCause.NewRoom || cause === RoomUpdateCause.RoomRemoved) {
-                return this.handleSplice(room, cause);
-            }
-
-            if (cause !== RoomUpdateCause.Timeline && cause !== RoomUpdateCause.ReadReceipt) {
-                throw new Error(`Unsupported update cause: ${cause}`);
-            }
-
-            const category = this.getRoomCategory(room);
-            if (this.sortingAlgorithm === SortAlgorithm.Manual) {
-                return; // Nothing to do here.
-            }
-
-            const roomIdx = this.getRoomIndex(room);
-            if (roomIdx === -1) {
-                throw new Error(`Room ${room.roomId} has no index in ${this.tagId}`);
-            }
-
-            // Try to avoid doing array operations if we don't have to: only move rooms within
-            // the categories if we're jumping categories
-            const oldCategory = this.getCategoryFromIndices(roomIdx, this.indices);
-            if (oldCategory !== category) {
-                // Move the room and update the indices
-                this.moveRoomIndexes(1, oldCategory, category, this.indices);
-                this.cachedOrderedRooms.splice(roomIdx, 1); // splice out the old index (fixed position)
-                this.cachedOrderedRooms.splice(this.indices[category], 0, room); // splice in the new room (pre-adjusted)
-                // Note: if moveRoomIndexes() is called after the splice then the insert operation
-                // will happen in the wrong place. Because we would have already adjusted the index
-                // for the category, we don't need to determine how the room is moving in the list.
-                // If we instead tried to insert before updating the indices, we'd have to determine
-                // whether the room was moving later (towards IDLE) or earlier (towards RED) from its
-                // current position, as it'll affect the category's start index after we remove the
-                // room from the array.
-            }
-
-            // Sort the category now that we've dumped the room in
-            await this.sortCategory(category);
-
-            return true; // change made
-        } finally {
-            await this.updateLock.release();
+    public handleRoomUpdate(room: Room, cause: RoomUpdateCause): boolean {
+        if (cause === RoomUpdateCause.NewRoom || cause === RoomUpdateCause.RoomRemoved) {
+            return this.handleSplice(room, cause);
         }
+
+        if (cause !== RoomUpdateCause.Timeline && cause !== RoomUpdateCause.ReadReceipt) {
+            throw new Error(`Unsupported update cause: ${cause}`);
+        }
+
+        const category = this.getRoomCategory(room);
+        if (this.sortingAlgorithm === SortAlgorithm.Manual) {
+            return; // Nothing to do here.
+        }
+
+        const roomIdx = this.getRoomIndex(room);
+        if (roomIdx === -1) {
+            throw new Error(`Room ${room.roomId} has no index in ${this.tagId}`);
+        }
+
+        // Try to avoid doing array operations if we don't have to: only move rooms within
+        // the categories if we're jumping categories
+        const oldCategory = this.getCategoryFromIndices(roomIdx, this.indices);
+        if (oldCategory !== category) {
+            // Move the room and update the indices
+            this.moveRoomIndexes(1, oldCategory, category, this.indices);
+            this.cachedOrderedRooms.splice(roomIdx, 1); // splice out the old index (fixed position)
+            this.cachedOrderedRooms.splice(this.indices[category], 0, room); // splice in the new room (pre-adjusted)
+            // Note: if moveRoomIndexes() is called after the splice then the insert operation
+            // will happen in the wrong place. Because we would have already adjusted the index
+            // for the category, we don't need to determine how the room is moving in the list.
+            // If we instead tried to insert before updating the indices, we'd have to determine
+            // whether the room was moving later (towards IDLE) or earlier (towards RED) from its
+            // current position, as it'll affect the category's start index after we remove the
+            // room from the array.
+        }
+
+        // Sort the category now that we've dumped the room in
+        this.sortCategory(category);
+
+        return true; // change made
     }
 
-    private async sortCategory(category: NotificationColor) {
+    private sortCategory(category: NotificationColor) {
         // This should be relatively quick because the room is usually inserted at the top of the
         // category, and most popular sorting algorithms will deal with trying to keep the active
         // room at the top/start of the category. For the few algorithms that will have to move the
@@ -201,7 +195,7 @@ export class ImportanceAlgorithm extends OrderingAlgorithm {
         const startIdx = this.indices[category];
         const numSort = nextCategoryStartIdx - startIdx; // splice() returns up to the max, so MAX_SAFE_INT is fine
         const unsortedSlice = this.cachedOrderedRooms.splice(startIdx, numSort);
-        const sorted = await sortRoomsWithAlgorithm(unsortedSlice, this.tagId, this.sortingAlgorithm);
+        const sorted = sortRoomsWithAlgorithm(unsortedSlice, this.tagId, this.sortingAlgorithm);
         this.cachedOrderedRooms.splice(startIdx, 0, ...sorted);
     }
 
diff --git a/src/stores/room-list/algorithms/list-ordering/NaturalAlgorithm.ts b/src/stores/room-list/algorithms/list-ordering/NaturalAlgorithm.ts
index cc2a28d892..91182dee16 100644
--- a/src/stores/room-list/algorithms/list-ordering/NaturalAlgorithm.ts
+++ b/src/stores/room-list/algorithms/list-ordering/NaturalAlgorithm.ts
@@ -29,42 +29,32 @@ export class NaturalAlgorithm extends OrderingAlgorithm {
         super(tagId, initialSortingAlgorithm);
     }
 
-    public async setRooms(rooms: Room[]): Promise<any> {
-        this.cachedOrderedRooms = await sortRoomsWithAlgorithm(rooms, this.tagId, this.sortingAlgorithm);
+    public setRooms(rooms: Room[]): void {
+        this.cachedOrderedRooms = sortRoomsWithAlgorithm(rooms, this.tagId, this.sortingAlgorithm);
     }
 
-    public async handleRoomUpdate(room, cause): Promise<boolean> {
-        try {
-            await this.updateLock.acquireAsync();
-
-            const isSplice = cause === RoomUpdateCause.NewRoom || cause === RoomUpdateCause.RoomRemoved;
-            const isInPlace = cause === RoomUpdateCause.Timeline || cause === RoomUpdateCause.ReadReceipt;
-            if (!isSplice && !isInPlace) {
-                throw new Error(`Unsupported update cause: ${cause}`);
-            }
-
-            if (cause === RoomUpdateCause.NewRoom) {
-                this.cachedOrderedRooms.push(room);
-            } else if (cause === RoomUpdateCause.RoomRemoved) {
-                const idx = this.getRoomIndex(room);
-                if (idx >= 0) {
-                    this.cachedOrderedRooms.splice(idx, 1);
-                } else {
-                    console.warn(`Tried to remove unknown room from ${this.tagId}: ${room.roomId}`);
-                }
-            }
-
-            // TODO: Optimize this to avoid useless operations: https://github.com/vector-im/element-web/issues/14457
-            // For example, we can skip updates to alphabetic (sometimes) and manually ordered tags
-            this.cachedOrderedRooms = await sortRoomsWithAlgorithm(
-                this.cachedOrderedRooms,
-                this.tagId,
-                this.sortingAlgorithm,
-            );
-
-            return true;
-        } finally {
-            await this.updateLock.release();
+    public handleRoomUpdate(room, cause): boolean {
+        const isSplice = cause === RoomUpdateCause.NewRoom || cause === RoomUpdateCause.RoomRemoved;
+        const isInPlace = cause === RoomUpdateCause.Timeline || cause === RoomUpdateCause.ReadReceipt;
+        if (!isSplice && !isInPlace) {
+            throw new Error(`Unsupported update cause: ${cause}`);
         }
+
+        if (cause === RoomUpdateCause.NewRoom) {
+            this.cachedOrderedRooms.push(room);
+        } else if (cause === RoomUpdateCause.RoomRemoved) {
+            const idx = this.getRoomIndex(room);
+            if (idx >= 0) {
+                this.cachedOrderedRooms.splice(idx, 1);
+            } else {
+                console.warn(`Tried to remove unknown room from ${this.tagId}: ${room.roomId}`);
+            }
+        }
+
+        // TODO: Optimize this to avoid useless operations: https://github.com/vector-im/element-web/issues/14457
+        // For example, we can skip updates to alphabetic (sometimes) and manually ordered tags
+        this.cachedOrderedRooms = sortRoomsWithAlgorithm(this.cachedOrderedRooms, this.tagId, this.sortingAlgorithm);
+
+        return true;
     }
 }
diff --git a/src/stores/room-list/algorithms/list-ordering/OrderingAlgorithm.ts b/src/stores/room-list/algorithms/list-ordering/OrderingAlgorithm.ts
index c47a35523c..23a8e33a41 100644
--- a/src/stores/room-list/algorithms/list-ordering/OrderingAlgorithm.ts
+++ b/src/stores/room-list/algorithms/list-ordering/OrderingAlgorithm.ts
@@ -26,7 +26,6 @@ import AwaitLock from "await-lock";
 export abstract class OrderingAlgorithm {
     protected cachedOrderedRooms: Room[];
     protected sortingAlgorithm: SortAlgorithm;
-    protected readonly updateLock = new AwaitLock();
 
     protected constructor(protected tagId: TagID, initialSortingAlgorithm: SortAlgorithm) {
         // noinspection JSIgnoredPromiseFromCall
@@ -45,21 +44,20 @@ export abstract class OrderingAlgorithm {
      * @param newAlgorithm The new algorithm. Must be defined.
      * @returns Resolves when complete.
      */
-    public async setSortAlgorithm(newAlgorithm: SortAlgorithm) {
+    public setSortAlgorithm(newAlgorithm: SortAlgorithm) {
         if (!newAlgorithm) throw new Error("A sorting algorithm must be defined");
         this.sortingAlgorithm = newAlgorithm;
 
         // Force regeneration of the rooms
-        await this.setRooms(this.orderedRooms);
+        this.setRooms(this.orderedRooms);
     }
 
     /**
      * Sets the rooms the algorithm should be handling, implying a reconstruction
      * of the ordering.
      * @param rooms The rooms to use going forward.
-     * @returns Resolves when complete.
      */
-    public abstract setRooms(rooms: Room[]): Promise<any>;
+    public abstract setRooms(rooms: Room[]): void;
 
     /**
      * Handle a room update. The Algorithm will only call this for causes which
@@ -69,7 +67,7 @@ export abstract class OrderingAlgorithm {
      * @param cause The cause of the update.
      * @returns True if the update requires the Algorithm to update the presentation layers.
      */
-    public abstract handleRoomUpdate(room: Room, cause: RoomUpdateCause): Promise<boolean>;
+    public abstract handleRoomUpdate(room: Room, cause: RoomUpdateCause): boolean;
 
     protected getRoomIndex(room: Room): number {
         let roomIdx = this.cachedOrderedRooms.indexOf(room);
diff --git a/src/stores/room-list/algorithms/tag-sorting/AlphabeticAlgorithm.ts b/src/stores/room-list/algorithms/tag-sorting/AlphabeticAlgorithm.ts
index b016a4256c..45f6eaf843 100644
--- a/src/stores/room-list/algorithms/tag-sorting/AlphabeticAlgorithm.ts
+++ b/src/stores/room-list/algorithms/tag-sorting/AlphabeticAlgorithm.ts
@@ -23,7 +23,7 @@ import { compare } from "../../../../utils/strings";
  * Sorts rooms according to the browser's determination of alphabetic.
  */
 export class AlphabeticAlgorithm implements IAlgorithm {
-    public async sortRooms(rooms: Room[], tagId: TagID): Promise<Room[]> {
+    public sortRooms(rooms: Room[], tagId: TagID): Room[] {
         return rooms.sort((a, b) => {
             return compare(a.name, b.name);
         });
diff --git a/src/stores/room-list/algorithms/tag-sorting/IAlgorithm.ts b/src/stores/room-list/algorithms/tag-sorting/IAlgorithm.ts
index 6c22ee0c9c..588bbbffc9 100644
--- a/src/stores/room-list/algorithms/tag-sorting/IAlgorithm.ts
+++ b/src/stores/room-list/algorithms/tag-sorting/IAlgorithm.ts
@@ -25,7 +25,7 @@ export interface IAlgorithm {
      * Sorts the given rooms according to the sorting rules of the algorithm.
      * @param {Room[]} rooms The rooms to sort.
      * @param {TagID} tagId The tag ID in which the rooms are being sorted.
-     * @returns {Promise<Room[]>} Resolves to the sorted rooms.
+     * @returns {Room[]} Returns the sorted rooms.
      */
-    sortRooms(rooms: Room[], tagId: TagID): Promise<Room[]>;
+    sortRooms(rooms: Room[], tagId: TagID): Room[];
 }
diff --git a/src/stores/room-list/algorithms/tag-sorting/ManualAlgorithm.ts b/src/stores/room-list/algorithms/tag-sorting/ManualAlgorithm.ts
index b8c0357633..9be8ba5262 100644
--- a/src/stores/room-list/algorithms/tag-sorting/ManualAlgorithm.ts
+++ b/src/stores/room-list/algorithms/tag-sorting/ManualAlgorithm.ts
@@ -22,7 +22,7 @@ import { IAlgorithm } from "./IAlgorithm";
  * Sorts rooms according to the tag's `order` property on the room.
  */
 export class ManualAlgorithm implements IAlgorithm {
-    public async sortRooms(rooms: Room[], tagId: TagID): Promise<Room[]> {
+    public sortRooms(rooms: Room[], tagId: TagID): Room[] {
         const getOrderProp = (r: Room) => r.tags[tagId].order || 0;
         return rooms.sort((a, b) => {
             return getOrderProp(a) - getOrderProp(b);
diff --git a/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts b/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts
index 49cfd9e520..f47458d1b1 100644
--- a/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts
+++ b/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts
@@ -97,7 +97,7 @@ export const sortRooms = (rooms: Room[]): Room[] => {
  * useful to the user.
  */
 export class RecentAlgorithm implements IAlgorithm {
-    public async sortRooms(rooms: Room[], tagId: TagID): Promise<Room[]> {
+    public sortRooms(rooms: Room[], tagId: TagID): Room[] {
         return sortRooms(rooms);
     }
 }
diff --git a/src/stores/room-list/algorithms/tag-sorting/index.ts b/src/stores/room-list/algorithms/tag-sorting/index.ts
index c22865f5ba..368c76f111 100644
--- a/src/stores/room-list/algorithms/tag-sorting/index.ts
+++ b/src/stores/room-list/algorithms/tag-sorting/index.ts
@@ -46,8 +46,8 @@ export function getSortingAlgorithmInstance(algorithm: SortAlgorithm): IAlgorith
  * @param {Room[]} rooms The rooms to sort.
  * @param {TagID} tagId The tag in which the sorting is occurring.
  * @param {SortAlgorithm} algorithm The algorithm to use for sorting.
- * @returns {Promise<Room[]>} Resolves to the sorted rooms.
+ * @returns {Room[]} Returns the sorted rooms.
  */
-export function sortRoomsWithAlgorithm(rooms: Room[], tagId: TagID, algorithm: SortAlgorithm): Promise<Room[]> {
+export function sortRoomsWithAlgorithm(rooms: Room[], tagId: TagID, algorithm: SortAlgorithm): Room[] {
     return getSortingAlgorithmInstance(algorithm).sortRooms(rooms, tagId);
 }