diff --git a/src/libs/actions/OnyxUpdates.ts b/src/libs/actions/OnyxUpdates.ts
index 0bc422d639bc..98688c91fc03 100644
--- a/src/libs/actions/OnyxUpdates.ts
+++ b/src/libs/actions/OnyxUpdates.ts
@@ -10,7 +10,7 @@ import ONYXKEYS from '@src/ONYXKEYS';
 import type {OnyxUpdateEvent, OnyxUpdatesFromServer, Request} from '@src/types/onyx';
 import type Response from '@src/types/onyx/Response';
 import {isEmptyObject} from '@src/types/utils/EmptyObject';
-import {queueOnyxUpdates} from './QueuedOnyxUpdates';
+import {queueOnyxOptimisticUpdates, queueOnyxUpdates} from './QueuedOnyxUpdates';
 
 // This key needs to be separate from ONYXKEYS.ONYX_UPDATES_FROM_SERVER so that it can be updated without triggering the callback when the server IDs are updated. If that
 // callback were triggered it would lead to duplicate processing of server updates.
@@ -33,6 +33,9 @@ function applyHTTPSOnyxUpdates(request: Request, response: Response) {
     // the UI. See https://github.com/Expensify/App/issues/12775 for more info.
     const updateHandler: (updates: OnyxUpdate[]) => Promise<unknown> = request?.data?.apiRequestType === CONST.API_REQUEST_TYPE.WRITE ? queueOnyxUpdates : Onyx.update;
 
+    // Push the front-end data like optimisticData, successData, failureData, finallyData of write requests to another queue to apply them after the responses are updated in onyx. This ensures that data like `isLoading` is only applied after the API response is written to local storage.
+    const updateOptimisticHandler: (updates: OnyxUpdate[]) => Promise<unknown> = request?.data?.apiRequestType === CONST.API_REQUEST_TYPE.WRITE ? queueOnyxOptimisticUpdates : Onyx.update;
+
     // First apply any onyx data updates that are being sent back from the API. We wait for this to complete and then
     // apply successData or failureData. This ensures that we do not update any pending, loading, or other UI states contained
     // in successData/failureData until after the component has received and API data.
@@ -41,7 +44,7 @@ function applyHTTPSOnyxUpdates(request: Request, response: Response) {
         .then(() => {
             // Handle the request's success/failure data (client-side data)
             if (response.jsonCode === 200 && request.successData) {
-                return updateHandler(request.successData);
+                return updateOptimisticHandler(request.successData);
             }
             if (response.jsonCode !== 200 && request.failureData) {
                 // 460 jsonCode in Expensify world means "admin required".
@@ -52,13 +55,13 @@ function applyHTTPSOnyxUpdates(request: Request, response: Response) {
                     Log.info('[OnyxUpdateManager] Received 460 status code, not applying failure data');
                     return Promise.resolve();
                 }
-                return updateHandler(request.failureData);
+                return updateOptimisticHandler(request.failureData);
             }
             return Promise.resolve();
         })
         .then(() => {
             if (request.finallyData) {
-                return updateHandler(request.finallyData);
+                return updateOptimisticHandler(request.finallyData);
             }
             return Promise.resolve();
         })
diff --git a/src/libs/actions/QueuedOnyxUpdates.ts b/src/libs/actions/QueuedOnyxUpdates.ts
index 76709c0152f3..fe433aaf33da 100644
--- a/src/libs/actions/QueuedOnyxUpdates.ts
+++ b/src/libs/actions/QueuedOnyxUpdates.ts
@@ -6,6 +6,7 @@ import ONYXKEYS from '@src/ONYXKEYS';
 // In this file we manage a queue of Onyx updates while the SequentialQueue is processing. There are functions to get the updates and clear the queue after saving the updates in Onyx.
 
 let queuedOnyxUpdates: OnyxUpdate[] = [];
+let queuedOnyxOptimisticUpdates: OnyxUpdate[] = [];
 let currentAccountID: number | undefined;
 
 Onyx.connect({
@@ -24,6 +25,15 @@ function queueOnyxUpdates(updates: OnyxUpdate[]): Promise<void> {
     return Promise.resolve();
 }
 
+/**
+ * @param queues optimistic onyx updates to be applied later when flushing the queue
+ */
+function queueOnyxOptimisticUpdates(updates: OnyxUpdate[]): Promise<void> {
+    queuedOnyxOptimisticUpdates = queuedOnyxOptimisticUpdates.concat(updates);
+
+    return Promise.resolve();
+}
+
 function flushQueue(): Promise<void> {
     if (!currentAccountID && !CONFIG.IS_TEST_ENV && !CONFIG.E2E_TESTING) {
         const preservedKeys: OnyxKey[] = [
@@ -44,15 +54,20 @@ function flushQueue(): Promise<void> {
         ];
 
         queuedOnyxUpdates = queuedOnyxUpdates.filter((update) => preservedKeys.includes(update.key as OnyxKey));
+        queuedOnyxOptimisticUpdates = queuedOnyxOptimisticUpdates.filter((update) => preservedKeys.includes(update.key as OnyxKey));
     }
 
-    return Onyx.update(queuedOnyxUpdates).then(() => {
-        queuedOnyxUpdates = [];
-    });
+    return Onyx.update(queuedOnyxUpdates)
+        .then(() => Onyx.update(queuedOnyxOptimisticUpdates))
+        .then(() => {
+            queuedOnyxUpdates = [];
+            queuedOnyxOptimisticUpdates = [];
+            return Promise.resolve();
+        });
 }
 
 function isEmpty() {
     return queuedOnyxUpdates.length === 0;
 }
 
-export {queueOnyxUpdates, flushQueue, isEmpty};
+export {queueOnyxUpdates, flushQueue, isEmpty, queueOnyxOptimisticUpdates};
