diff --git a/packages/rocketchat-authorization/server/publications/permissions.js b/packages/rocketchat-authorization/server/publications/permissions.js
index fa8b41c7183682c0b15ace8f158e06ba11887be1..02499e961bfa8598b46b98cfbe496bdd156c3340 100644
--- a/packages/rocketchat-authorization/server/publications/permissions.js
+++ b/packages/rocketchat-authorization/server/publications/permissions.js
@@ -8,7 +8,8 @@ Meteor.methods({
 			return {
 				update: records.filter((record) => {
 					return record._updatedAt > updatedAt;
-				})
+				}),
+				remove: RocketChat.models.Permissions.trashFindDeletedAfter(updatedAt, {}, {fields: {_id: 1, _deletedAt: 1}}).fetch()
 			};
 		}
 
diff --git a/packages/rocketchat-lib/client/lib/cachedCollection.js b/packages/rocketchat-lib/client/lib/cachedCollection.js
index 347728d69b5fdbcb8f2b84d9be118bcf64663eb4..1973ddb6f37476a6d4e9b56012ec4e65b4e00f64 100644
--- a/packages/rocketchat-lib/client/lib/cachedCollection.js
+++ b/packages/rocketchat-lib/client/lib/cachedCollection.js
@@ -4,12 +4,26 @@ class CachedCollectionManager {
 	constructor() {
 		this.items = [];
 		this._syncEnabled = false;
+		this.reconnectCb = [];
 
 		const _unstoreLoginToken = Accounts._unstoreLoginToken;
 		Accounts._unstoreLoginToken = (...args) => {
 			_unstoreLoginToken.apply(Accounts, args);
 			this.clearAllCache();
 		};
+
+		let connectionWasOnline = true;
+		Tracker.autorun(() => {
+			const connected = Meteor.connection.status().connected;
+
+			if (connected === true && connectionWasOnline === false) {
+				for (const cb of this.reconnectCb) {
+					cb();
+				}
+			}
+
+			connectionWasOnline = connected;
+		});
 	}
 
 	register(cachedCollection) {
@@ -36,6 +50,10 @@ class CachedCollectionManager {
 	get syncEnabled() {
 		return this._syncEnabled;
 	}
+
+	onReconnect(cb) {
+		this.reconnectCb.push(cb);
+	}
 }
 
 RocketChat.CachedCollectionManager = new CachedCollectionManager;
@@ -49,7 +67,7 @@ class CachedCollection {
 		syncMethodName,
 		eventName,
 		eventType = 'onUser',
-		useSync = false,
+		useSync = true,
 		useCache = false,
 		debug = true,
 		version = 1,
@@ -70,6 +88,10 @@ class CachedCollection {
 		this.updatedAt = new Date(0);
 		this.maxCacheTime = maxCacheTime;
 
+		if (this.useCache === false) {
+			return this.clearCache();
+		}
+
 		RocketChat.CachedCollectionManager.register(this);
 	}
 
@@ -166,28 +188,48 @@ class CachedCollection {
 		this.log(`syncing from ${this.updatedAt}`);
 
 		Meteor.call(this.syncMethodName, this.updatedAt, (error, data) => {
+			let changes = [];
+
 			if (data.update && data.update.length > 0) {
 				this.log(`${data.update.length} records updated in sync`);
-
-				for (const record of data.update) {
-					delete record.$loki;
-					this.collection.upsert({ _id: record._id }, _.omit(record, '_id'));
-
-					if (record._updatedAt && record._updatedAt > this.updatedAt) {
-						this.updatedAt = record._updatedAt;
-					}
-				}
+				changes.push(...data.update);
 			}
 
 			if (data.remove && data.remove.length > 0) {
 				this.log(`${data.remove.length} records removed in sync`);
+				changes.push(...data.remove);
+			}
+
+			changes = changes.sort((a, b) => {
+				const valueA = a._updatedAt || a._deletedAt;
+				const valueB = b._updatedAt || b._deletedAt;
 
-				for (const record of data.remove) {
+				if (valueA < valueB) {
+					return -1;
+				}
+
+				if (valueA > valueB) {
+					return 1;
+				}
+
+				return 0;
+			});
+
+			for (const record of changes) {
+				delete record.$loki;
+
+				if (record._deletedAt) {
 					this.collection.remove({ _id: record._id });
 
 					if (record._deletedAt && record._deletedAt > this.updatedAt) {
 						this.updatedAt = record._deletedAt;
 					}
+				} else {
+					this.collection.upsert({ _id: record._id }, _.omit(record, '_id'));
+
+					if (record._updatedAt && record._updatedAt > this.updatedAt) {
+						this.updatedAt = record._updatedAt;
+					}
 				}
 			}
 
@@ -198,6 +240,10 @@ class CachedCollection {
 	}
 
 	saveCache(data) {
+		if (this.useCache === false) {
+			return;
+		}
+
 		this.log('saving cache');
 		if (!data) {
 			data = this.collection.find().fetch();
@@ -256,15 +302,8 @@ class CachedCollection {
 			}
 
 			if (this.useSync === true) {
-				let connectionWasOnline = true;
-				Tracker.autorun(() => {
-					const connected = Meteor.connection.status().connected;
-
-					if (connected === true && connectionWasOnline === false) {
-						this.trySync();
-					}
-
-					connectionWasOnline = connected;
+				RocketChat.CachedCollectionManager.onReconnect(() => {
+					this.trySync();
 				});
 			}
 
diff --git a/packages/rocketchat-lib/server/publications/settings.coffee b/packages/rocketchat-lib/server/publications/settings.coffee
index 8b5c90c489cca8dca8e97f3578b768c5f6ddd03f..6e5fe56c46c6cbf9d9f50c488cfda1268a4e6cb8 100644
--- a/packages/rocketchat-lib/server/publications/settings.coffee
+++ b/packages/rocketchat-lib/server/publications/settings.coffee
@@ -31,6 +31,7 @@ Meteor.methods
 			return {
 				update: records.filter (record) ->
 					return record._updatedAt > updatedAt
+				remove: RocketChat.models.Settings.trashFindDeletedAfter(updatedAt, {hidden: { $ne: true }}, {fields: {_id: 1, _deletedAt: 1}}).fetch()
 			}
 
 		return records
diff --git a/server/publications/room.js b/server/publications/room.js
index 6a5965c4176f2e98b1de5353987fbeca07100492..7822a9d336afc68127d32a01249fd8fb3c05e02b 100644
--- a/server/publications/room.js
+++ b/server/publications/room.js
@@ -38,8 +38,9 @@ Meteor.methods({
 			return {
 				update: data
 					.filter(record => { return record._room && record._room._updatedAt > updatedAt; })
-					.map(roomMap)
-				};
+					.map(roomMap),
+				remove: RocketChat.models.Subscriptions.trashFindDeletedAfter(updatedAt, {'u._id': Meteor.userId()}, {fields: {_id: 1, _deletedAt: 1}}).fetch()
+			};
 		}
 
 		return data.map(roomMap);
diff --git a/server/publications/subscription.coffee b/server/publications/subscription.coffee
index 41750dbedfca45107d5832c60cf77f7c6166aab8..79d0e75e12bfd531ebed9fcb4a18a5a808ab5f4b 100644
--- a/server/publications/subscription.coffee
+++ b/server/publications/subscription.coffee
@@ -35,6 +35,7 @@ Meteor.methods
 			return {
 				update: records.filter (record) ->
 					return record._updatedAt > updatedAt
+				remove: RocketChat.models.Subscriptions.trashFindDeletedAfter(updatedAt, {'u._id': Meteor.userId()}, {fields: {_id: 1, _deletedAt: 1}}).fetch()
 			}
 
 		return records