diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
index 8b5dd7a1..b0b7f4fd 100644
--- a/src/android/camera_device.cpp
+++ b/src/android/camera_device.cpp
@@ -955,7 +955,9 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques
 	 * The descriptor and the associated memory reserved here are freed
 	 * at request complete time.
 	 */
-	Camera3RequestDescriptor descriptor(camera_.get(), camera3Request);
+	std::unique_ptr<Camera3RequestDescriptor> descriptor =
+		std::make_unique<Camera3RequestDescriptor>(camera_.get(),
+							   camera3Request);
 
 	/*
 	 * \todo The Android request model is incremental, settings passed in
@@ -966,12 +968,12 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques
 	if (camera3Request->settings)
 		lastSettings_ = camera3Request->settings;
 	else
-		descriptor.settings_ = lastSettings_;
+		descriptor->settings_ = lastSettings_;
 
-	LOG(HAL, Debug) << "Queueing request " << descriptor.request_->cookie()
-			<< " with " << descriptor.buffers_.size() << " streams";
-	for (unsigned int i = 0; i < descriptor.buffers_.size(); ++i) {
-		const camera3_stream_buffer_t &camera3Buffer = descriptor.buffers_[i];
+	LOG(HAL, Debug) << "Queueing request " << descriptor->request_->cookie()
+			<< " with " << descriptor->buffers_.size() << " streams";
+	for (unsigned int i = 0; i < descriptor->buffers_.size(); ++i) {
+		const camera3_stream_buffer_t &camera3Buffer = descriptor->buffers_[i];
 		camera3_stream *camera3Stream = camera3Buffer.stream;
 		CameraStream *cameraStream = static_cast<CameraStream *>(camera3Stream->priv);
 
@@ -1003,12 +1005,12 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques
 			 * associate it with the Camera3RequestDescriptor for
 			 * lifetime management only.
 			 */
-			descriptor.frameBuffers_.push_back(
+			descriptor->frameBuffers_.push_back(
 				createFrameBuffer(*camera3Buffer.buffer,
 						  cameraStream->configuration().pixelFormat,
 						  cameraStream->configuration().size));
 
-			buffer = descriptor.frameBuffers_.back().get();
+			buffer = descriptor->frameBuffers_.back().get();
 			LOG(HAL, Debug) << ss.str() << " (direct)";
 			break;
 
@@ -1030,7 +1032,7 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques
 			return -ENOMEM;
 		}
 
-		descriptor.request_->addBuffer(cameraStream->stream(), buffer,
+		descriptor->request_->addBuffer(cameraStream->stream(), buffer,
 						camera3Buffer.acquire_fence);
 	}
 
@@ -1038,7 +1040,7 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques
 	 * Translate controls from Android to libcamera and queue the request
 	 * to the CameraWorker thread.
 	 */
-	int ret = processControls(&descriptor);
+	int ret = processControls(descriptor.get());
 	if (ret)
 		return ret;
 
@@ -1066,11 +1068,11 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques
 		state_ = State::Running;
 	}
 
-	CaptureRequest *request = descriptor.request_.get();
+	CaptureRequest *request = descriptor->request_.get();
 
 	{
 		MutexLocker descriptorsLock(descriptorsMutex_);
-		descriptors_[descriptor.request_->cookie()] = std::move(descriptor);
+		descriptors_.push_back(std::move(descriptor));
 	}
 
 	worker_.queueRequest(request);
@@ -1080,31 +1082,27 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques
 
 void CameraDevice::requestComplete(Request *request)
 {
-	decltype(descriptors_)::node_type node;
-	{
-		MutexLocker descriptorsLock(descriptorsMutex_);
-		auto it = descriptors_.find(request->cookie());
-		if (it == descriptors_.end()) {
-			/*
-			 * \todo Clarify if the Camera has to be closed on
-			 * ERROR_DEVICE and possibly demote the Fatal to simple
-			 * Error.
-			 */
-			notifyError(0, nullptr, CAMERA3_MSG_ERROR_DEVICE);
-			LOG(HAL, Fatal)
-				<< "Unknown request: " << request->cookie();
+	if (descriptors_.empty())
+		return;
 
-			return;
-		}
+	Camera3RequestDescriptor *descriptor = descriptors_.front().get();
+	if (descriptor->request_->cookie() != request->cookie()) {
+		/*
+		 * \todo Clarify if the Camera has to be closed on
+		 * ERROR_DEVICE and possibly demote the Fatal to simple
+		 * Error.
+		 */
+		notifyError(0, nullptr, CAMERA3_MSG_ERROR_DEVICE);
+		LOG(HAL, Fatal)
+			<< "Unknown request: " << request->cookie();
 
-		node = descriptors_.extract(it);
+		return;
 	}
-	Camera3RequestDescriptor &descriptor = node.mapped();
 
 	camera3_capture_result_t captureResult = {};
-	captureResult.frame_number = descriptor.frameNumber_;
-	captureResult.num_output_buffers = descriptor.buffers_.size();
-	captureResult.output_buffers = descriptor.buffers_.data();
+	captureResult.frame_number = descriptor->frameNumber_;
+	captureResult.num_output_buffers = descriptor->buffers_.size();
+	captureResult.output_buffers = descriptor->buffers_.data();
 
 	/*
 	 * If the Request has failed, abort the request by notifying the error
@@ -1115,11 +1113,11 @@ void CameraDevice::requestComplete(Request *request)
 				<< " not successfully completed: "
 				<< request->status();
 
-		notifyError(descriptor.frameNumber_, nullptr,
+		notifyError(descriptor->frameNumber_, nullptr,
 			    CAMERA3_MSG_ERROR_REQUEST);
 
 		captureResult.partial_result = 0;
-		for (camera3_stream_buffer_t &buffer : descriptor.buffers_) {
+		for (camera3_stream_buffer_t &buffer : descriptor->buffers_) {
 			CameraStream *cameraStream =
 				static_cast<CameraStream *>(buffer.stream->priv);
 
@@ -1142,6 +1140,7 @@ void CameraDevice::requestComplete(Request *request)
 		}
 		callbacks_->process_capture_result(callbacks_, &captureResult);
 
+		descriptors_.pop_front();
 		return;
 	}
 
@@ -1153,10 +1152,10 @@ void CameraDevice::requestComplete(Request *request)
 	 */
 	uint64_t sensorTimestamp = static_cast<uint64_t>(request->metadata()
 							 .get(controls::SensorTimestamp));
-	notifyShutter(descriptor.frameNumber_, sensorTimestamp);
+	notifyShutter(descriptor->frameNumber_, sensorTimestamp);
 
 	LOG(HAL, Debug) << "Request " << request->cookie() << " completed with "
-			<< descriptor.buffers_.size() << " streams";
+			<< descriptor->buffers_.size() << " streams";
 
 	/*
 	 * Generate the metadata associated with the captured buffers.
@@ -1166,14 +1165,14 @@ void CameraDevice::requestComplete(Request *request)
 	 */
 	std::unique_ptr<CameraMetadata> resultMetadata = getResultMetadata(descriptor);
 	if (!resultMetadata) {
-		notifyError(descriptor.frameNumber_, nullptr, CAMERA3_MSG_ERROR_RESULT);
+		notifyError(descriptor->frameNumber_, nullptr, CAMERA3_MSG_ERROR_RESULT);
 
 		/* The camera framework expects an empty metadata pack on error. */
 		resultMetadata = std::make_unique<CameraMetadata>(0, 0);
 	}
 
 	/* Handle post-processing. */
-	for (camera3_stream_buffer_t &buffer : descriptor.buffers_) {
+	for (camera3_stream_buffer_t &buffer : descriptor->buffers_) {
 		CameraStream *cameraStream =
 			static_cast<CameraStream *>(buffer.stream->priv);
 
@@ -1184,13 +1183,13 @@ void CameraDevice::requestComplete(Request *request)
 		if (!src) {
 			LOG(HAL, Error) << "Failed to find a source stream buffer";
 			buffer.status = CAMERA3_BUFFER_STATUS_ERROR;
-			notifyError(descriptor.frameNumber_, buffer.stream,
+			notifyError(descriptor->frameNumber_, buffer.stream,
 				    CAMERA3_MSG_ERROR_BUFFER);
 			continue;
 		}
 
 		int ret = cameraStream->process(*src, buffer,
-						descriptor.settings_,
+						descriptor->settings_,
 						resultMetadata.get());
 		/*
 		 * Return the FrameBuffer to the CameraStream now that we're
@@ -1201,7 +1200,7 @@ void CameraDevice::requestComplete(Request *request)
 
 		if (ret) {
 			buffer.status = CAMERA3_BUFFER_STATUS_ERROR;
-			notifyError(descriptor.frameNumber_, buffer.stream,
+			notifyError(descriptor->frameNumber_, buffer.stream,
 				    CAMERA3_MSG_ERROR_BUFFER);
 		}
 	}
@@ -1210,7 +1209,7 @@ void CameraDevice::requestComplete(Request *request)
 	 * Finalize the capture result by setting fences and buffer status
 	 * before executing the callback.
 	 */
-	for (camera3_stream_buffer_t &buffer : descriptor.buffers_) {
+	for (camera3_stream_buffer_t &buffer : descriptor->buffers_) {
 		buffer.acquire_fence = -1;
 		buffer.release_fence = -1;
 		buffer.status = CAMERA3_BUFFER_STATUS_OK;
@@ -1219,6 +1218,8 @@ void CameraDevice::requestComplete(Request *request)
 
 	captureResult.result = resultMetadata->get();
 	callbacks_->process_capture_result(callbacks_, &captureResult);
+
+	descriptors_.pop_front();
 }
 
 std::string CameraDevice::logPrefix() const
@@ -1254,10 +1255,10 @@ void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream,
  * Produce a set of fixed result metadata.
  */
 std::unique_ptr<CameraMetadata>
-CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) const
+CameraDevice::getResultMetadata(const Camera3RequestDescriptor *descriptor) const
 {
-	const ControlList &metadata = descriptor.request_->metadata();
-	const CameraMetadata &settings = descriptor.settings_;
+	const ControlList &metadata = descriptor->request_->metadata();
+	const CameraMetadata &settings = descriptor->settings_;
 	camera_metadata_ro_entry_t entry;
 	bool found;
 
diff --git a/src/android/camera_device.h b/src/android/camera_device.h
index 43eb5895..5889a0e7 100644
--- a/src/android/camera_device.h
+++ b/src/android/camera_device.h
@@ -7,6 +7,7 @@
 #ifndef __ANDROID_CAMERA_DEVICE_H__
 #define __ANDROID_CAMERA_DEVICE_H__
 
+#include <deque>
 #include <map>
 #include <memory>
 #include <mutex>
@@ -105,7 +106,7 @@ private:
 			 camera3_error_msg_code code);
 	int processControls(Camera3RequestDescriptor *descriptor);
 	std::unique_ptr<CameraMetadata> getResultMetadata(
-		const Camera3RequestDescriptor &descriptor) const;
+		const Camera3RequestDescriptor *descriptor) const;
 
 	unsigned int id_;
 	camera3_device_t camera3Device_;
@@ -125,7 +126,7 @@ private:
 	std::vector<CameraStream> streams_;
 
 	libcamera::Mutex descriptorsMutex_; /* Protects descriptors_. */
-	std::map<uint64_t, Camera3RequestDescriptor> descriptors_;
+	std::deque<std::unique_ptr<Camera3RequestDescriptor>> descriptors_;
 
 	std::string maker_;
 	std::string model_;
