diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h
index a6ba4a07..5959e86e 100644
--- a/include/libcamera/internal/software_isp/software_isp.h
+++ b/include/libcamera/internal/software_isp/software_isp.h
@@ -102,6 +102,7 @@ private:
 	DebayerParams debayerParams_;
 	std::queue<uint32_t> availableParams_;
 	bool allocateParamsBuffers(const unsigned int bufferCount);
+	std::queue<uint32_t> availableStats_;
 	std::unique_ptr<SwStatsCpu> allocateStatsBuffers(
 		std::vector<SharedFD> &fdStats,
 		const unsigned int bufferCount);
diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp
index 1e224b6f..c4ad22be 100644
--- a/src/libcamera/software_isp/software_isp.cpp
+++ b/src/libcamera/software_isp/software_isp.cpp
@@ -191,6 +191,7 @@ std::unique_ptr<SwStatsCpu> SoftwareIsp::allocateStatsBuffers(
 		unsigned int bufferId = shared.fd().get();
 		fdStats.emplace_back(shared.fd());
 		sharedStats->emplace(bufferId, std::move(shared));
+		availableStats_.push(bufferId);
 	}
 
 	auto stats = std::make_unique<SwStatsCpu>(std::move(sharedStats));
@@ -413,11 +414,18 @@ void SoftwareIsp::process(uint32_t frame, FrameBuffer *input, FrameBuffer *outpu
 		while (availableParams_.empty())
 			;
 	}
+	if (availableStats_.empty()) {
+		LOG(SoftwareIsp, Error) << "Statistics buffer underrun";
+		/* Well, busy loop, but this situation shouldn't normally happen. */
+		while (availableStats_.empty())
+			;
+	}
 
 	const uint32_t paramsBufferId = availableParams_.front();
 	availableParams_.pop();
+	const uint32_t statsBufferId = availableStats_.front();
+	availableStats_.pop();
 	ipa_->prepare(frame, paramsBufferId);
-	const uint32_t statsBufferId = 0;
 	debayer_->invokeMethod(&DebayerCpu::process,
 			       ConnectionTypeQueued, frame,
 			       statsBufferId, paramsBufferId, input, output);
@@ -443,8 +451,9 @@ void SoftwareIsp::statsReady(uint32_t frame, const uint32_t statsBufferId)
 	ispStatsReady.emit(frame, statsBufferId);
 }
 
-void SoftwareIsp::statsProcessed([[maybe_unused]] const uint32_t statsBufferId)
+void SoftwareIsp::statsProcessed(const uint32_t statsBufferId)
 {
+	availableStats_.push(statsBufferId);
 }
 
 void SoftwareIsp::inputReady(FrameBuffer *input)
