diff --git a/emper/io/Future.cpp b/emper/io/Future.cpp
index 71a6dab8e053b1745028ffecc0afd53fa7b05959..d374fe24e31a8c5a95a7e3a36313141d631791f3 100644
--- a/emper/io/Future.cpp
+++ b/emper/io/Future.cpp
@@ -77,7 +77,7 @@ void Future::submit() {
 
 	LOGD("submit " << this << " to IoContext " << io);
 
-	io->submit(*this);
+	io->submitAndReap(*this);
 }
 
 auto Future::cancel() -> int32_t {
diff --git a/emper/io/IoContext.cpp b/emper/io/IoContext.cpp
index 9ec288ea91d00bcee96384efed67b72df719080e..8d12e712835d854d223601368e6c8067d63e42ef 100644
--- a/emper/io/IoContext.cpp
+++ b/emper/io/IoContext.cpp
@@ -172,14 +172,6 @@ void IoContext::submit(Future &future) {
 
 	// we have submitted all our prepared sqes
 	preparedSqes.clear();
-
-	// io_uring will try to synchronously complete any IO request before
-	// offloading it to the async backend. See io_uring_enter(2).
-	// Immediate offloading can be enforced by setting the IOSQE_ASYNC flag in the sqe.
-	// Try to reap a possible synchronous completion if we are on a worker's io_uring.
-	if constexpr (callerEnvironment == CallerEnvironment::EMPER) {
-		reapAndScheduleCompletions();
-	}
 }
 
 // show the compiler our template incarnations
diff --git a/emper/io/IoContext.hpp b/emper/io/IoContext.hpp
index df99e8c177396212fe9fc6df6c49b03ec3b09b89..af07b659dfb64c1963b58d5cef51b7125f88e3d5 100644
--- a/emper/io/IoContext.hpp
+++ b/emper/io/IoContext.hpp
@@ -166,12 +166,31 @@ class IoContext : public Logger<LogSubsystem::IO> {
 	/**
 	 * @brief Submit a future for asynchronous completion in this IoContext
 	 *
-	 * @param future The Future which should be completed. The Future object
-	 *        must stay valid until it is completed.
+	 * @param future The Future which should be submited to the io_uring.
+	 *        The Future object must stay valid until it is completed.
 	 */
 	template <CallerEnvironment callerEnvironment = CallerEnvironment::EMPER>
 	void submit(Future &future);
 
+	/**
+	 * @brief Submit a future for asynchronous completion in this IoContext and reap completions
+	 *
+	 * Submit a Future from within the Runtime and reap possible inline completions
+	 * directly afterwards
+	 *
+	 * @param future The Future which should be submited to the io_uring.
+	 *        The Future object must stay valid until it is completed.
+	 */
+	void submitAndReap(Future &future) {
+		assert(Runtime::inRuntime());
+		submit<CallerEnvironment::EMPER>(future);
+		// io_uring will try to synchronously complete any IO request before
+		// offloading it to the async backend. See io_uring_enter(2).
+		// Immediate offloading can be enforced by setting the IOSQE_ASYNC flag in the sqe.
+		// Try to reap a possible synchronous completions.
+		reapAndScheduleCompletions();
+	}
+
 	/**
 	 * @brief Collect all fibers waiting on completed IO
 	 *