diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,5 @@
 # Changelog for keid-core
 
-## Unreleased changes
+## 0.1.0.1
+
+- Inter-stage resource release waits for render job to finish.
diff --git a/keid-core.cabal b/keid-core.cabal
--- a/keid-core.cabal
+++ b/keid-core.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           keid-core
-version:        0.1.0.0
+version:        0.1.0.1
 synopsis:       Core parts of Keid engine.
 category:       Game Engine
 author:         IC Rainbow
diff --git a/src/Engine/Run.hs b/src/Engine/Run.hs
--- a/src/Engine/Run.hs
+++ b/src/Engine/Run.hs
@@ -53,20 +53,34 @@
   put (Just oldSR)
   case stageAction of
     StageDone -> do
-      logInfo "Stage done"
-      release stageRelease
+      releaseStage "Stage done"
       runStack rest
     StageReplace nextStage -> do
-      logInfo "Stage replaced"
-      release stageRelease
+      releaseStage "Stage replaced"
       runStack (nextStage : rest)
     StagePush frozenStage nextStage -> do
       case frozenStage of
         StackStage{} ->
-          logInfo "Restarting stage pushed"
+          logDebug "Restarting stage pushed"
         StackStageContinue{} ->
-          logInfo "Frozen stage pushed"
+          logDebug "Frozen stage pushed"
       runStack (nextStage : frozenStage : rest)
+  where
+    releaseStage label = do
+      logDebug label
+      void $! async do
+        {-
+          XXX: wait for the current render job to finish.
+
+          Since the new frames wouldn't be submitted until the control flow
+          gets back to the render loop, this should be enough of a signal that
+          the stage resources aren't used anymore.
+
+          The call is costly, but its effects aren't seen.
+        -}
+        asks getDevice >>= Vk.deviceWaitIdle
+        release stageRelease
+        logDebug $ label <> ", released"
 
 prepareStage
   :: StageRIO env (ReleaseKey, st)
