diff --git a/src/public/javascripts/services/load_results.js b/src/public/javascripts/services/load_results.js
index a04fae2f7..690aba3ee 100644
--- a/src/public/javascripts/services/load_results.js
+++ b/src/public/javascripts/services/load_results.js
@@ -12,6 +12,8 @@ export class LoadResults {
         this.noteReorderings = [];
 
         this.noteRevisions = [];
+
+        this.contentNoteIdToSourceId = [];
     }
 
     addNote(noteId, sourceId) {
@@ -76,4 +78,16 @@ export class LoadResults {
         const sourceIds = this.noteIdToSourceId[noteId];
         return sourceIds && !!sourceIds.find(sId => sId !== sourceId);
     }
+
+    addNoteContent(noteId, sourceId) {
+        this.contentNoteIdToSourceId.push({noteId, sourceId});
+    }
+
+    isNoteContentReloaded(noteId, sourceId) {
+        if (!noteId) {
+            return false;
+        }
+
+        return this.contentNoteIdToSourceId.find(l => l.noteId === noteId && l.sourceId !== sourceId);
+    }
 }
\ No newline at end of file
diff --git a/src/public/javascripts/services/tree_cache.js b/src/public/javascripts/services/tree_cache.js
index 404c52775..b550f3732 100644
--- a/src/public/javascripts/services/tree_cache.js
+++ b/src/public/javascripts/services/tree_cache.js
@@ -328,7 +328,10 @@ class TreeCache {
             }
         });
 
-        // missing reloading the relation target note
+        syncRows.filter(sync => sync.entityName === 'note_contents').forEach(sync => {
+            loadResults.addNoteContent(sync.entityId, sync.sourceId);
+        });
+
         syncRows.filter(sync => sync.entityName === 'note_revisions').forEach(sync => {
             loadResults.addNoteRevision(sync.entityId, sync.noteId, sync.sourceId);
         });
diff --git a/src/public/javascripts/widgets/note_detail.js b/src/public/javascripts/widgets/note_detail.js
index 9c0fa13ab..dadb9d09f 100644
--- a/src/public/javascripts/widgets/note_detail.js
+++ b/src/public/javascripts/widgets/note_detail.js
@@ -4,6 +4,7 @@ import protectedSessionHolder from "../services/protected_session_holder.js";
 import SpacedUpdate from "../services/spaced_update.js";
 import server from "../services/server.js";
 import libraryLoader from "../services/library_loader.js";
+import noteDetailService from "../services/note_detail.js";
 
 const TPL = `
 
@@ -220,8 +221,12 @@ export default class NoteDetailWidget extends TabAwareWidget {
         this.refresh();
     }
 
-    entitiesReloadedListener({loadResults}) {
-        if (loadResults.isNoteReloaded(this.noteId, this.componentId)) {
+    async entitiesReloadedListener({loadResults}) {
+        if (loadResults.isNoteContentReloaded(this.noteId, this.componentId)) {
+            this.tabContext.noteFull = await noteDetailService.loadNoteFull(this.noteId);
+
+            console.log("Reloaded", this.tabContext.noteFull);
+
             this.refreshWithNote(this.note, this.notePath);
         }
     }
diff --git a/src/routes/routes.js b/src/routes/routes.js
index 626046346..bf9596685 100644
--- a/src/routes/routes.js
+++ b/src/routes/routes.js
@@ -1,3 +1,5 @@
+import * as syncService from "../services/sync.js";
+
 const setupRoute = require('./setup');
 const loginRoute = require('./login');
 const indexRoute = require('./index');
@@ -53,7 +55,7 @@ const csrfMiddleware = csurf({
 });
 
 function apiResultHandler(req, res, result) {
-    res.setHeader('trilium-max-sync-id', syncTableService.getMaxSyncId());
+    res.setHeader('trilium-max-sync-id', syncService.getMaxSyncId());
 
     // if it's an array and first element is integer then we consider this to be [statusCode, response] format
     if (Array.isArray(result) && result.length > 0 && Number.isInteger(result[0])) {
diff --git a/src/services/cls.js b/src/services/cls.js
index 387fb7bc5..44201d951 100644
--- a/src/services/cls.js
+++ b/src/services/cls.js
@@ -21,6 +21,18 @@ function isEntityEventsDisabled() {
     return !!namespace.get('disableEntityEvents');
 }
 
+function getSyncRows() {
+    return namespace.get('syncRows') || [];
+}
+
+function addSyncRow(syncRow) {
+    const syncRows = getSyncRows();
+
+    syncRows.push(syncRow);
+
+    namespace.set('syncRows', syncRows);
+}
+
 function reset() {
     clsHooked.reset();
 }
@@ -32,5 +44,7 @@ module.exports = {
     getSourceId,
     disableEntityEvents,
     isEntityEventsDisabled,
-    reset
+    reset,
+    getSyncRows,
+    addSyncRow
 };
\ No newline at end of file
diff --git a/src/services/sql.js b/src/services/sql.js
index 299729348..d352818e4 100644
--- a/src/services/sql.js
+++ b/src/services/sql.js
@@ -207,6 +207,8 @@ async function transactional(func) {
 
             await commit();
 
+            require('./ws.js').sendPingToAllClients();
+
             transactionActive = false;
             resolve();
         }
diff --git a/src/services/sync_table.js b/src/services/sync_table.js
index 75906e7d4..ac1076f07 100644
--- a/src/services/sync_table.js
+++ b/src/services/sync_table.js
@@ -4,8 +4,6 @@ const dateUtils = require('./date_utils');
 const log = require('./log');
 const cls = require('./cls');
 
-let syncs = [];
-
 async function insertEntitySync(entityName, entityId, sourceId) {
     const sync = {
         entityName: entityName,
@@ -22,9 +20,7 @@ async function insertEntitySync(entityName, entityId, sourceId) {
 async function addEntitySync(entityName, entityId, sourceId) {
     const sync = await insertEntitySync(entityName, entityId, sourceId);
 
-    syncs.push(sync);
-
-    setTimeout(() => require('./ws').sendPingToAllClients(), 50);
+    cls.addSyncRow(sync);
 }
 
 async function addEntitySyncsForSector(entityName, entityPrimaryKey, sector) {
@@ -35,14 +31,6 @@ async function addEntitySyncsForSector(entityName, entityPrimaryKey, sector) {
     }
 }
 
-function getMaxSyncId() {
-    return syncs.length === 0 ? 0 : syncs[syncs.length - 1].id;
-}
-
-function getEntitySyncsNewerThan(syncId) {
-    return syncs.filter(s => s.id > syncId);
-}
-
 async function cleanupSyncRowsForMissingEntities(entityName, entityPrimaryKey) {
     await sql.execute(`
       DELETE 
@@ -114,7 +102,5 @@ module.exports = {
     addApiTokenSync: async (apiTokenId, sourceId) => await addEntitySync("api_tokens", apiTokenId, sourceId),
     addEntitySync,
     fillAllSyncRows,
-    getEntitySyncsNewerThan,
-    getMaxSyncId,
     addEntitySyncsForSector
 };
\ No newline at end of file
diff --git a/src/services/ws.js b/src/services/ws.js
index a2964d293..76ce1d158 100644
--- a/src/services/ws.js
+++ b/src/services/ws.js
@@ -2,6 +2,7 @@ const WebSocket = require('ws');
 const utils = require('./utils');
 const log = require('./log');
 const sql = require('./sql');
+const cls = require('./cls');
 const syncMutexService = require('./sync_mutex');
 
 let webSocketServer;
@@ -89,11 +90,10 @@ async function fillInAdditionalProperties(sync) {
 }
 
 async function sendPing(client) {
-    const syncData = require('./sync_table')
-        .getEntitySyncsNewerThan(lastAcceptedSyncIds[client.id])
+    const syncRows = cls.getSyncRows()
         .filter(r => r.entityName !== 'recent_notes'); // only noise ...
 
-    for (const sync of syncData) {
+    for (const sync of syncRows) {
         try {
             await fillInAdditionalProperties(sync);
         }
@@ -107,7 +107,7 @@ async function sendPing(client) {
 
     sendMessage(client, {
         type: 'sync',
-        data: syncData,
+        data: syncRows,
         outstandingSyncs: stats.outstandingPushes + stats.outstandingPulls
     });
 }