diff --git a/.gitignore b/.gitignore
index db1bd34dba500694f0839ab25758ec769f24529b..c1461bc43c7a3eb2a3e8a686eec39cff66b799d2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@
 /build-*/
 
 /.cache/
+/.clangd/
 
 subprojects/packagecache/
 subprojects/googletest*
diff --git a/emper/Runtime.cpp b/emper/Runtime.cpp
index 5c36d3b4183462e409bb48ed689084e4a72559c4..a49128b9c3fe71af90ea0e6eac8176069d2e8250 100644
--- a/emper/Runtime.cpp
+++ b/emper/Runtime.cpp
@@ -165,7 +165,7 @@ Runtime::~Runtime() {
 	// objects bound to the runtime's lifetime
 	if constexpr (emper::STATS) {
 		printLastRuntimeStats();
-		emper::io::Stats::printWorkerStats();
+		emper::io::Stats::printStats(globalIo, ioContexts);
 	}
 
 	for (unsigned int i = 0; i < workerCount; ++i) {
diff --git a/emper/io/IoContext.hpp b/emper/io/IoContext.hpp
index 2f34771e2156554c583b92d6c7090de8bf1b66e1..ee4d78ebfeb1567b8883fedfe0fff24f4c6e37c9 100644
--- a/emper/io/IoContext.hpp
+++ b/emper/io/IoContext.hpp
@@ -181,5 +181,7 @@ class IoContext : public Logger<LogSubsystem::IO> {
 			}
 		}
 	}
+
+	auto getStats() -> Stats & { return stats; };
 };
 }	 // namespace emper::io
diff --git a/emper/io/Stats.cpp b/emper/io/Stats.cpp
index ba4ffe4bedd90ac4225802558cb1567126061b62..62b792c807b59cf83e50f077187f81bba9a9d649 100644
--- a/emper/io/Stats.cpp
+++ b/emper/io/Stats.cpp
@@ -7,13 +7,12 @@
 #include <string>						 // for operator<<, to_string
 #include <utility>					 // for pair
 
+#include "io/IoContext.hpp"
 #include "io/Operation.hpp"	 // for Operation, operator<<, Operation::RECV
 #include "lib/math.hpp"
 
 namespace emper::io {
 
-std::vector<Stats*> Stats::workerStats;
-
 auto operator<<(std::ostream& os, const Stats::CompletionType& t) -> std::ostream& {
 	switch (t) {
 		case Stats::CompletionType::FullCompletion:
@@ -118,10 +117,9 @@ auto operator<<(std::ostream& os, const Stats& s) -> std::ostream& {
 	return os;
 }
 
-void Stats::printWorkerStats() {
-	auto* globalStats = workerStats.front();
-	workerStats.erase(workerStats.begin());
-	std::cout << *globalStats << std::endl;
+void Stats::printStats(IoContext* globalIoContext,
+											 const std::vector<IoContext*>& workerIoContexts) {
+	std::cout << globalIoContext->getStats() << std::endl;
 
 	// Use a stats object to calculate the averages
 	Stats avgs;
@@ -130,7 +128,8 @@ void Stats::printWorkerStats() {
 
 	// calculate avgs
 	int i = 1;
-	for (auto& stats : workerStats) {
+	for (auto* workerIoContext : workerIoContexts) {
+		auto* stats = &workerIoContext->getStats();
 		for (const auto& op_pair : stats->io_uring_completions) {
 			auto op = op_pair.first;
 			auto op_map = op_pair.second;
diff --git a/emper/io/Stats.hpp b/emper/io/Stats.hpp
index 776d247a631d5513246b1197c837926db395c37b..5114800ee26424b71ef80f2312087a45c55bd126 100644
--- a/emper/io/Stats.hpp
+++ b/emper/io/Stats.hpp
@@ -24,6 +24,11 @@
 #include "lib/math.hpp"
 
 class Runtime;	// lines 28-28
+namespace emper {
+namespace io {
+class IoContext;
+}
+}	 // namespace emper
 
 namespace math = emper::lib::math;
 
@@ -52,8 +57,6 @@ class Stats {
 	int workerId = 0;
 	static_assert(sizeof(int) > sizeof(workerid_t));
 
-	static std::vector<Stats*> workerStats;
-
 	enum CompletionType {
 		FullCompletion = 0,
 		ErrorCompletion,
@@ -125,13 +128,10 @@ class Stats {
 	unsigned reReapCount_max = 0;
 	boost::circular_buffer<unsigned> reReapCount_last;
 
-	static void printWorkerStats();
+	static void printStats(IoContext* globalIoContext,
+												 const std::vector<IoContext*>& workerIoContexts);
 
-	Stats() : reReapCount_last(10) {
-		if constexpr (emper::STATS) {
-			workerStats.push_back(this);
-		}
-	}
+	Stats() : reReapCount_last(10) {}
 
 	void recordCompletion(const Future& f, const int32_t& res) {
 		record_completion(f.op, res, PartialCompletableFuture::DISABLE_PARTIAL_COMPLETION, f.len);