diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 519cad4f..71dd311f 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -153,12 +153,16 @@ private:
 	int allocateBuffers(Camera *camera);
 	int freeBuffers(Camera *camera);
 
+	int queuePendingRequests();
+
 	ImgUDevice imgu0_;
 	ImgUDevice imgu1_;
 	MediaDevice *cio2MediaDev_;
 	MediaDevice *imguMediaDev_;
 
 	std::vector<IPABuffer> ipaBuffers_;
+
+	std::queue<std::pair<IPU3CameraData *, Request *>> pendingRequests_;
 };
 
 IPU3CameraConfiguration::IPU3CameraConfiguration(IPU3CameraData *data)
@@ -764,6 +768,8 @@ void PipelineHandlerIPU3::stop(Camera *camera)
 	IPU3CameraData *data = cameraData(camera);
 	int ret = 0;
 
+	pendingRequests_ = {};
+
 	data->ipa_->stop();
 
 	ret |= data->imgu_->stop();
@@ -774,36 +780,50 @@ void PipelineHandlerIPU3::stop(Camera *camera)
 	freeBuffers(camera);
 }
 
-int PipelineHandlerIPU3::queueRequestDevice(Camera *camera, Request *request)
+int PipelineHandlerIPU3::queuePendingRequests()
 {
-	IPU3CameraData *data = cameraData(camera);
+	while (!pendingRequests_.empty()) {
+		IPU3CameraData *data = pendingRequests_.front().first;
+		Request *request = pendingRequests_.front().second;
 
-	IPU3Frames::Info *info = data->frameInfos_.create(request);
-	if (!info)
-		return -ENOBUFS;
+		IPU3Frames::Info *info = data->frameInfos_.create(request);
+		if (!info)
+			break;
 
-	/*
-	 * Queue a buffer on the CIO2, using the raw stream buffer provided in
-	 * the request, if any, or a CIO2 internal buffer otherwise.
-	 */
-	FrameBuffer *reqRawBuffer = request->findBuffer(&data->rawStream_);
-	FrameBuffer *rawBuffer = data->cio2_.queueBuffer(request, reqRawBuffer);
-	if (!rawBuffer) {
-		data->frameInfos_.remove(info);
-		return -ENOMEM;
-	}
+		/*
+		 * Queue a buffer on the CIO2, using the raw stream buffer
+		 * provided in the request, if any, or a CIO2 internal buffer
+		 * otherwise.
+		 */
+		FrameBuffer *reqRawBuffer = request->findBuffer(&data->rawStream_);
+		FrameBuffer *rawBuffer = data->cio2_.queueBuffer(request, reqRawBuffer);
+		if (!rawBuffer) {
+			data->frameInfos_.remove(info);
+			break;
+		}
 
-	info->rawBuffer = rawBuffer;
+		info->rawBuffer = rawBuffer;
 
-	ipa::ipu3::IPU3Event ev;
-	ev.op = ipa::ipu3::EventProcessControls;
-	ev.frame = info->id;
-	ev.controls = request->controls();
-	data->ipa_->processEvent(ev);
+		ipa::ipu3::IPU3Event ev;
+		ev.op = ipa::ipu3::EventProcessControls;
+		ev.frame = info->id;
+		ev.controls = request->controls();
+		data->ipa_->processEvent(ev);
+
+		pendingRequests_.pop();
+	}
 
 	return 0;
 }
 
+int PipelineHandlerIPU3::queueRequestDevice(Camera *camera, Request *request)
+{
+	IPU3CameraData *data = cameraData(camera);
+
+	pendingRequests_.emplace(data, request);
+	return queuePendingRequests();
+}
+
 bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator)
 {
 	int ret;
