diff --git a/app/assets/javascripts/work_items/components/notes/work_item_add_note.vue b/app/assets/javascripts/work_items/components/notes/work_item_add_note.vue
index 4ea88842dc6bdef57ec45944d8d95bf5dc828bca..efa40b647900498c62f3718ecfadcdb4af6c5955 100644
--- a/app/assets/javascripts/work_items/components/notes/work_item_add_note.vue
+++ b/app/assets/javascripts/work_items/components/notes/work_item_add_note.vue
@@ -9,7 +9,9 @@ import { clearDraft } from '~/lib/utils/autosave';
 import { findWidget } from '~/issues/list/utils';
 import DiscussionReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
 import ResolveDiscussionButton from '~/notes/components/discussion_resolve_button.vue';
+import { updateCacheAfterCreatingNote } from '../../graphql/cache_utils';
 import createNoteMutation from '../../graphql/notes/create_work_item_note.mutation.graphql';
+import workItemNotesByIidQuery from '../../graphql/notes/work_item_notes_by_iid.query.graphql';
 import workItemByIidQuery from '../../graphql/work_item_by_iid.query.graphql';
 import { TRACKING_CATEGORY_SHOW, WIDGET_TYPE_EMAIL_PARTICIPANTS, i18n } from '../../constants';
 import WorkItemNoteSignedOut from './work_item_note_signed_out.vue';
@@ -276,11 +278,27 @@ export default {
       this.isEditing = true;
       this.$emit('startReplying');
     },
-    onNoteUpdate(store, createNoteData) {
-      const numErrors = createNoteData.data?.createNote?.errors?.length;
+    addDiscussionToCache(cache, newNote) {
+      const queryArgs = {
+        query: workItemNotesByIidQuery,
+        variables: { fullPath: this.fullPath, iid: this.workItemIid },
+      };
+      const sourceData = cache.readQuery(queryArgs);
+      if (!sourceData) {
+        return;
+      }
+      cache.writeQuery({
+        ...queryArgs,
+        data: updateCacheAfterCreatingNote(sourceData, newNote),
+      });
+    },
+    onNoteUpdate(cache, { data }) {
+      this.addDiscussionToCache(cache, data.createNote.note);
+
+      const numErrors = data?.createNote?.errors?.length;
 
       if (numErrors) {
-        const { errors } = createNoteData.data.createNote;
+        const { errors } = data.createNote;
 
         // TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/503600
         // Refetching widgets as a temporary solution for dynamic updates
@@ -304,7 +322,7 @@ export default {
           return;
         }
 
-        throw new Error(createNoteData.data?.createNote?.errors[0]);
+        throw new Error(data?.createNote?.errors[0]);
       }
     },
   },
diff --git a/app/assets/javascripts/work_items/components/work_item_created_updated.vue b/app/assets/javascripts/work_items/components/work_item_created_updated.vue
index 8082d83c6594c42798b1c407810eb0028b694eee..0a532a397b32f76199395fb6f4790fb51f799f17 100644
--- a/app/assets/javascripts/work_items/components/work_item_created_updated.vue
+++ b/app/assets/javascripts/work_items/components/work_item_created_updated.vue
@@ -6,7 +6,7 @@ import { WORKSPACE_PROJECT } from '~/issues/constants';
 import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
 import ConfidentialityBadge from '~/vue_shared/components/confidentiality_badge.vue';
 import workItemByIidQuery from '../graphql/work_item_by_iid.query.graphql';
-import { isNotesWidget } from '../utils';
+import { findNotesWidget } from '../utils';
 import WorkItemStateBadge from './work_item_state_badge.vue';
 import WorkItemTypeIcon from './work_item_type_icon.vue';
 
@@ -57,7 +57,7 @@ export default {
       return this.workItem?.workItemType?.iconName;
     },
     isDiscussionLocked() {
-      return this.workItem?.widgets?.find(isNotesWidget)?.discussionLocked;
+      return findNotesWidget(this.workItem)?.discussionLocked;
     },
     isWorkItemConfidential() {
       return this.workItem?.confidential;
diff --git a/app/assets/javascripts/work_items/components/work_item_notes.vue b/app/assets/javascripts/work_items/components/work_item_notes.vue
index 94127e68a06b967c6c29d0c58aa5e95d8dcab8d6..530a7c905ace981e905629ada3044f4d38386766 100644
--- a/app/assets/javascripts/work_items/components/work_item_notes.vue
+++ b/app/assets/javascripts/work_items/components/work_item_notes.vue
@@ -307,8 +307,8 @@ export default {
       subscribeToMore: [
         {
           document: workItemNoteCreatedSubscription,
-          updateQuery(previousResult, { subscriptionData }) {
-            return updateCacheAfterCreatingNote(previousResult, subscriptionData);
+          updateQuery(previousResult, { subscriptionData: { data } }) {
+            return updateCacheAfterCreatingNote(previousResult, data?.workItemNoteCreated);
           },
           variables() {
             return {
diff --git a/app/assets/javascripts/work_items/components/work_item_sticky_header.vue b/app/assets/javascripts/work_items/components/work_item_sticky_header.vue
index 283ddef5c1db44e31427a93e9d3817f9afb14d1e..cd0703961a7815ea993b3f1f648f392dee9de345 100644
--- a/app/assets/javascripts/work_items/components/work_item_sticky_header.vue
+++ b/app/assets/javascripts/work_items/components/work_item_sticky_header.vue
@@ -4,7 +4,7 @@ import LockedBadge from '~/issuable/components/locked_badge.vue';
 import { WORKSPACE_PROJECT } from '~/issues/constants';
 import ConfidentialityBadge from '~/vue_shared/components/confidentiality_badge.vue';
 import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
-import { isNotesWidget } from '../utils';
+import { findNotesWidget } from '../utils';
 import WorkItemActions from './work_item_actions.vue';
 import TodosToggle from './shared/todos_toggle.vue';
 import WorkItemStateBadge from './work_item_state_badge.vue';
@@ -107,7 +107,7 @@ export default {
       return this.workItem.userPermissions?.reportSpam;
     },
     isDiscussionLocked() {
-      return this.workItem.widgets?.find(isNotesWidget)?.discussionLocked;
+      return findNotesWidget(this.workItem)?.discussionLocked;
     },
     workItemType() {
       return this.workItem.workItemType?.name;
diff --git a/app/assets/javascripts/work_items/graphql/cache_utils.js b/app/assets/javascripts/work_items/graphql/cache_utils.js
index 000915276918bdefdc77a8ae75d672296b637f8b..7ee9691487ffd640a55434e630bec59c3d326d71 100644
--- a/app/assets/javascripts/work_items/graphql/cache_utils.js
+++ b/app/assets/javascripts/work_items/graphql/cache_utils.js
@@ -12,10 +12,11 @@ import { findWidget } from '~/issues/list/utils';
 import {
   findHierarchyWidgets,
   findHierarchyWidgetChildren,
+  findNotesWidget,
+  getNewWorkItemAutoSaveKey,
   isNotesWidget,
   newWorkItemFullPath,
   newWorkItemId,
-  getNewWorkItemAutoSaveKey,
 } from '../utils';
 import {
   WIDGET_TYPE_ASSIGNEES,
@@ -41,8 +42,7 @@ import workItemByIidQuery from './work_item_by_iid.query.graphql';
 import workItemByIdQuery from './work_item_by_id.query.graphql';
 import getWorkItemTreeQuery from './work_item_tree.query.graphql';
 
-const getNotesWidgetFromSourceData = (draftData) =>
-  draftData?.workspace?.workItem?.widgets.find(isNotesWidget);
+const getNotesWidgetFromSourceData = (draftData) => findNotesWidget(draftData?.workspace?.workItem);
 
 const updateNotesWidgetDataInDraftData = (draftData, notesWidget) => {
   const noteWidgetIndex = draftData.workspace.workItem.widgets.findIndex(isNotesWidget);
@@ -53,13 +53,12 @@ const updateNotesWidgetDataInDraftData = (draftData, notesWidget) => {
  * Work Item note create subscription update query callback
  *
  * @param currentNotes
- * @param subscriptionData
+ * @param newNote
  */
-export const updateCacheAfterCreatingNote = (currentNotes, subscriptionData) => {
-  if (!subscriptionData.data?.workItemNoteCreated) {
+export const updateCacheAfterCreatingNote = (currentNotes, newNote) => {
+  if (!newNote) {
     return currentNotes;
   }
-  const newNote = subscriptionData.data.workItemNoteCreated;
 
   return produce(currentNotes, (draftData) => {
     const notesWidget = getNotesWidgetFromSourceData(draftData);
diff --git a/app/assets/javascripts/work_items/utils.js b/app/assets/javascripts/work_items/utils.js
index 38966ab9df420cdaf6e08cbf43739e3636576b4b..4585453e71eea32061cf5a46c908b1e631815e7e 100644
--- a/app/assets/javascripts/work_items/utils.js
+++ b/app/assets/javascripts/work_items/utils.js
@@ -48,6 +48,9 @@ export const findHierarchyWidgets = (widgets) =>
 export const findLinkedItemsWidget = (workItem) =>
   workItem.widgets?.find((widget) => widget.type === WIDGET_TYPE_LINKED_ITEMS);
 
+export const findNotesWidget = (workItem) =>
+  workItem?.widgets?.find((widget) => widget.type === WIDGET_TYPE_NOTES);
+
 export const findStartAndDueDateWidget = (workItem) =>
   workItem.widgets?.find((widget) => widget.type === WIDGET_TYPE_START_AND_DUE_DATE);
 
diff --git a/spec/frontend/work_items/graphql/cache_utils_spec.js b/spec/frontend/work_items/graphql/cache_utils_spec.js
index e2a2488425b2b5d8b79d462a0b4eb332e7f71644..0d6968f1f3381c3b5b3cb396e97898cb701cea9f 100644
--- a/spec/frontend/work_items/graphql/cache_utils_spec.js
+++ b/spec/frontend/work_items/graphql/cache_utils_spec.js
@@ -1,18 +1,22 @@
+import { cloneDeep } from 'lodash';
 import { WIDGET_TYPE_HIERARCHY } from '~/work_items/constants';
 import {
   addHierarchyChild,
   removeHierarchyChild,
   addHierarchyChildren,
   setNewWorkItemCache,
+  updateCacheAfterCreatingNote,
   updateCountsForParent,
 } from '~/work_items/graphql/cache_utils';
-import { findHierarchyWidgets } from '~/work_items/utils';
+import { findHierarchyWidgets, findNotesWidget } from '~/work_items/utils';
 import getWorkItemTreeQuery from '~/work_items/graphql/work_item_tree.query.graphql';
 import waitForPromises from 'helpers/wait_for_promises';
 import { apolloProvider } from '~/graphql_shared/issuable_client';
 import {
-  workItemHierarchyResponse,
   childrenWorkItems,
+  createWorkItemNoteResponse,
+  mockWorkItemNotesByIidResponse,
+  workItemHierarchyResponse,
   workItemResponseFactory,
 } from '../mock_data';
 
@@ -462,6 +466,46 @@ describe('work items graphql cache utils', () => {
     });
   });
 
+  describe('updateCacheAfterCreatingNote', () => {
+    const findDiscussions = ({ workspace }) =>
+      findNotesWidget(workspace.workItem).discussions.nodes;
+
+    it('adds a new discussion to the notes widget', () => {
+      const currentNotes = mockWorkItemNotesByIidResponse.data;
+      const newNote = createWorkItemNoteResponse().data.createNote.note;
+
+      expect(findDiscussions(currentNotes)).toHaveLength(3);
+
+      const updatedNotes = updateCacheAfterCreatingNote(currentNotes, newNote);
+
+      expect(findDiscussions(updatedNotes)).toHaveLength(4);
+      expect(findDiscussions(updatedNotes).at(-1)).toBe(newNote.discussion);
+    });
+
+    it('does not modify notes widget when newNote is undefined', () => {
+      const currentNotes = mockWorkItemNotesByIidResponse.data;
+      const newNote = undefined;
+
+      expect(findDiscussions(currentNotes)).toHaveLength(3);
+
+      const updatedNotes = updateCacheAfterCreatingNote(currentNotes, newNote);
+
+      expect(findDiscussions(updatedNotes)).toHaveLength(3);
+    });
+
+    it('does not add duplicate discussions', () => {
+      const currentNotes = cloneDeep(mockWorkItemNotesByIidResponse.data);
+      const newNote = createWorkItemNoteResponse().data.createNote.note;
+      findDiscussions(currentNotes).push(newNote.discussion);
+
+      expect(findDiscussions(currentNotes)).toHaveLength(4);
+
+      const updatedNotes = updateCacheAfterCreatingNote(currentNotes, newNote);
+
+      expect(findDiscussions(updatedNotes)).toHaveLength(4);
+    });
+  });
+
   describe('updateCountsForParent', () => {
     const mockWorkItemData = workItemResponseFactory();
     const mockCache = {