diff --git a/emper/Emper.hpp b/emper/Emper.hpp
index 2138be46e5fbbe281492ff551e587464010de8dc..2bfbf49f739dd04d5a0418db7f96a5490b6079e6 100644
--- a/emper/Emper.hpp
+++ b/emper/Emper.hpp
@@ -97,4 +97,13 @@ static const bool IO_URING_SHARED_WQ =
 		false
 #endif
 		;
+
+enum class IoCompleterBehavior {
+	schedule,
+	wakeup,
+	none,
+};
+
+static const enum IoCompleterBehavior IO_COMPLETER_BEHAVIOR =
+		IoCompleterBehavior::EMPER_IO_COMPLETER_BEHAVIOR;
 }	 // namespace emper
diff --git a/emper/Runtime.cpp b/emper/Runtime.cpp
index 43ba9be7f3dfa3aef7e1905b90c52f9e108bd65c..e4b189749222f0913beda1faf4059a5c1e805074 100644
--- a/emper/Runtime.cpp
+++ b/emper/Runtime.cpp
@@ -92,7 +92,9 @@ Runtime::Runtime(workerid_t workerCount, RuntimeStrategyFactory& strategyFactory
 		// for each worker's IoContext one eventfd read is prepared before the
 		// globalCompleter is started and submits all previously prepared sqes.
 		globalIo = new GlobalIoContext(*this, workerCount);
-		globalIo->startGlobalCompleter();
+		if constexpr (emper::IO_COMPLETER_BEHAVIOR != emper::IoCompleterBehavior::none) {
+			globalIo->startGlobalCompleter();
+		}
 
 		if constexpr (emper::STATS) {
 			globalIo->stats.workerId = -1;
@@ -196,8 +198,10 @@ auto Runtime::workerLoop(Worker* worker) -> void* {
 	if constexpr (emper::IO) {
 		auto* workerIo = new IoContext(*this);
 
-		// submit the workers' CQ eventfds to the global IoContext
-		globalIo->registerWorkerIo(*workerIo);
+		if constexpr (emper::IO_COMPLETER_BEHAVIOR != emper::IoCompleterBehavior::none) {
+			// submit the workers' CQ eventfds to the global IoContext
+			globalIo->registerWorkerIo(*workerIo);
+		}
 		// notify the globalCompleter that we have registered our eventfd
 		ioReadySem.notify();
 
diff --git a/emper/io/GlobalIoContext.cpp b/emper/io/GlobalIoContext.cpp
index 27b4b0752f5f813676f839a3f7c3e73bc14e0c08..83799c7829130fab1908727fcfbb6994f33faeec 100644
--- a/emper/io/GlobalIoContext.cpp
+++ b/emper/io/GlobalIoContext.cpp
@@ -14,6 +14,7 @@
 
 #include "CallerEnvironment.hpp"
 #include "Common.hpp"
+#include "Emper.hpp"
 #include "Runtime.hpp"
 #include "io/Future.hpp"
 #include "io/IoContext.hpp"
@@ -82,7 +83,7 @@ auto GlobalIoContext::globalCompleterFunc(void* arg) -> void* {
 		//  -> there are completions on this worker IoContext
 		switch (tag) {
 			// clang-11 does not support [[likely]] yet
-			// TODO: remove the preprocessor check if clang ass [[likely]] support
+			// TODO: remove the preprocessor check if clang has [[likely]] support
 #if defined __has_attribute
 #if __has_attribute(likely)
 			[[likely]]	// NOLINT(clang-diagnostic-unknown-attributes)
@@ -103,7 +104,13 @@ auto GlobalIoContext::globalCompleterFunc(void* arg) -> void* {
 
 				assert(submitted == 1);
 
-				worker_io->reapAndScheduleCompletions<CallerEnvironment::ANYWHERE>();
+				if constexpr (emper::IO_COMPLETER_BEHAVIOR == emper::IoCompleterBehavior::wakeup) {
+					// Only wakeup sleeping workers and hope that the worker which
+					// has ready cqes will reap them soon.
+					globalIoContext->runtime.wakeupSleepingWorkers<CallerEnvironment::ANYWHERE>();
+				} else {
+					worker_io->reapAndScheduleCompletions<CallerEnvironment::ANYWHERE>();
+				}
 			}
 			break;
 
diff --git a/meson.build b/meson.build
index 9a6bca81395dbc6709f34424cceb7d1d02aca18a..276a7c4e1dd24563e7229d6aa5db5d999d2c9cb5 100644
--- a/meson.build
+++ b/meson.build
@@ -93,6 +93,16 @@ endforeach
 io_cq_lock_impl = get_option('io_cq_lock_implementation')
 conf_data.set('EMPER_IO_CQ_LOCK_' + io_cq_lock_impl.to_upper(), true)
 
+io_completer_behavior = get_option('io_completer_behavior')
+if io_completer_behavior == 'maybe_wakeup'
+	if get_option('worker_sleep')
+		io_completer_behavior = 'wakeup'
+	else
+		io_completer_behavior = 'none'
+	endif
+endif
+conf_data.set('EMPER_IO_COMPLETER_BEHAVIOR', io_completer_behavior)
+
 subdir('emper')
 subdir('tests')
 subdir('apps')
diff --git a/meson_options.txt b/meson_options.txt
index 06bd0206e6218ed75a6d44f669ca504ea368ef4e..ac1f842cd90c82f09a9b80c5cd3538b34b724f9b 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -122,3 +122,10 @@ option(
   choices: ['spin_lock', 'counting_try_lock', 'mutex'],
   value: 'counting_try_lock',
 )
+option(
+  'io_completer_behavior',
+  type: 'combo',
+  description: 'The behaviour of the IO completer thread',
+  choices: ['schedule', 'maybe_wakeup'],
+  value: 'schedule',
+)