diff --git a/Ryujinx.Graphics.Vulkan/AutoFlushCounter.cs b/Ryujinx.Graphics.Vulkan/AutoFlushCounter.cs
new file mode 100644
index 000000000..4ba689ccb
--- /dev/null
+++ b/Ryujinx.Graphics.Vulkan/AutoFlushCounter.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Diagnostics;
+
+namespace Ryujinx.Graphics.Vulkan
+{
+    internal class AutoFlushCounter
+    {
+        // How often to flush on framebuffer change.
+        private readonly static long FramebufferFlushTimer = Stopwatch.Frequency / 1000;
+
+        private const int MinDrawCountForFlush = 10;
+        private const int InitialQueryCountForFlush = 32;
+
+        private long _lastFlush;
+        private ulong _lastDrawCount;
+        private bool _hasPendingQuery;
+        private int _queryCount;
+
+        public void RegisterFlush(ulong drawCount)
+        {
+            _lastFlush = Stopwatch.GetTimestamp();
+            _lastDrawCount = drawCount;
+
+            _hasPendingQuery = false;
+        }
+
+        public bool RegisterPendingQuery()
+        {
+            _hasPendingQuery = true;
+
+            // Interrupt render passes to flush queries, so that early results arrive sooner.
+            if (++_queryCount == InitialQueryCountForFlush)
+            {
+                return true;
+            }
+
+            return false;
+        }
+
+        public bool ShouldFlushQuery()
+        {
+            return _hasPendingQuery;
+        }
+
+        public bool ShouldFlush(ulong drawCount)
+        {
+            _queryCount = 0;
+
+            if (_hasPendingQuery)
+            {
+                return true;
+            }
+
+            long draws = (long)(drawCount - _lastDrawCount);
+
+            if (draws < MinDrawCountForFlush)
+            {
+                if (draws == 0)
+                {
+                    _lastFlush = Stopwatch.GetTimestamp();
+                }
+
+                return false;
+            }
+
+            long flushTimeout = FramebufferFlushTimer;
+
+            long now = Stopwatch.GetTimestamp();
+
+            return now > _lastFlush + flushTimeout;
+        }
+    }
+}
diff --git a/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/Ryujinx.Graphics.Vulkan/PipelineBase.cs
index 769d4594e..5c666b09d 100644
--- a/Ryujinx.Graphics.Vulkan/PipelineBase.cs
+++ b/Ryujinx.Graphics.Vulkan/PipelineBase.cs
@@ -19,6 +19,8 @@ namespace Ryujinx.Graphics.Vulkan
         protected readonly Device Device;
         public readonly PipelineCache PipelineCache;
 
+        protected readonly AutoFlushCounter AutoFlush;
+
         private PipelineDynamicState _dynamicState;
         private PipelineState _newState;
         private bool _stateDirty;
@@ -70,6 +72,8 @@ namespace Ryujinx.Graphics.Vulkan
             Gd = gd;
             Device = device;
 
+            AutoFlush = new AutoFlushCounter();
+
             var pipelineCacheCreateInfo = new PipelineCacheCreateInfo()
             {
                 SType = StructureType.PipelineCacheCreateInfo
diff --git a/Ryujinx.Graphics.Vulkan/PipelineFull.cs b/Ryujinx.Graphics.Vulkan/PipelineFull.cs
index ca3a33ef8..c86929931 100644
--- a/Ryujinx.Graphics.Vulkan/PipelineFull.cs
+++ b/Ryujinx.Graphics.Vulkan/PipelineFull.cs
@@ -10,8 +10,6 @@ namespace Ryujinx.Graphics.Vulkan
     {
         private const ulong MinByteWeightForFlush = 256 * 1024 * 1024; // MB
 
-        private bool _hasPendingQuery;
-
         private readonly List<QueryPool> _activeQueries;
         private CounterQueueEvent _activeConditionalRender;
 
@@ -158,9 +156,8 @@ namespace Ryujinx.Graphics.Vulkan
 
         private void FlushPendingQuery()
         {
-            if (_hasPendingQuery)
+            if (AutoFlush.ShouldFlushQuery())
             {
-                _hasPendingQuery = false;
                 FlushCommandsImpl();
             }
         }
@@ -211,6 +208,7 @@ namespace Ryujinx.Graphics.Vulkan
 
         public void FlushCommandsImpl()
         {
+            AutoFlush.RegisterFlush(DrawCount);
             EndRenderPass();
 
             foreach (var queryPool in _activeQueries)
@@ -277,12 +275,18 @@ namespace Ryujinx.Graphics.Vulkan
         {
             _pendingQueryCopies.Add(query);
 
-            _hasPendingQuery = true;
+            if (AutoFlush.RegisterPendingQuery())
+            {
+                FlushCommandsImpl();
+            }
         }
 
         protected override void SignalAttachmentChange()
         {
-            FlushPendingQuery();
+            if (AutoFlush.ShouldFlush(DrawCount))
+            {
+                FlushCommandsImpl();
+            }
         }
 
         protected override void SignalRenderPassEnd()