diff --git a/engine/table/src/main/java/io/deephaven/engine/table/impl/SwapListener.java b/engine/table/src/main/java/io/deephaven/engine/table/impl/SwapListener.java
index b2c2f2ad9ca..065546881c2 100644
--- a/engine/table/src/main/java/io/deephaven/engine/table/impl/SwapListener.java
+++ b/engine/table/src/main/java/io/deephaven/engine/table/impl/SwapListener.java
@@ -157,10 +157,19 @@ protected synchronized boolean end(@SuppressWarnings("unused") final long clockC
 
         if (success) {
             eventualResult.setLastNotificationStep(lastNotificationStep);
-            referenceForSource.swapDelegate(initialDelegate, eventualListener instanceof LegacyListenerAdapter
-                    ? (LegacyListenerAdapter) eventualListener
-                    : new WeakSimpleReference<>(eventualListener));
-            forceReferenceCountToZero();
+
+            // note: the source table first increments the notification step before notifying children,
+            // deephaven-core#4556 was caused by a swap to the eventual listener prior to the children being notified.
+            // Therefore, we must defer the swap until after the children have been notified.
+            sourceTable.getUpdateGraph().addNotification(new TerminalNotification() {
+                @Override
+                public void run() {
+                    referenceForSource.swapDelegate(initialDelegate, eventualListener instanceof LegacyListenerAdapter
+                            ? (LegacyListenerAdapter) eventualListener
+                            : new WeakSimpleReference<>(eventualListener));
+                    SwapListener.this.forceReferenceCountToZero();
+                }
+            });
         }
 
         return success;