diff --git a/apps/EchoServer.cpp b/apps/EchoServer.cpp
index f179dc609a6263f8e77ddb26c4e91dec8e0b63e5..7b92494aef8287c659779e1774b268e0f479e290 100644
--- a/apps/EchoServer.cpp
+++ b/apps/EchoServer.cpp
@@ -9,12 +9,14 @@
 #include <cstdlib>
 #include <cstring>
 #include <iostream>
+#include <random>
 #include <string>
 
 #include "Common.hpp"
 #include "Debug.hpp"
 #include "Runtime.hpp"
-#include "Worker.hpp"
+#include "RuntimeBuilder.hpp"
+#include "emper-common.h"
 #include "emper-config.h"
 #include "io.hpp"
 
@@ -28,16 +30,35 @@ static const int BACKLOG = 1024;
 
 static unsigned int computations_us = 0;
 static unsigned int max_computations_us = 0;
+static float max_computations_probability = -1;
 
 static std::atomic<bool> quit = false;
 
+static thread_local std::mt19937 randGenerator;
+static auto getComputation() -> unsigned {
+	// fixed computation is computations_us
+	if (!max_computations_us) return computations_us;
+
+	// computation is in range [computations_us, max_computations_us]
+	if (max_computations_probability == -1) {
+		std::uniform_int_distribution<unsigned int> distribution(computations_us, max_computations_us);
+		return computations_us += distribution(randGenerator);
+	}
+
+	// computation is either computations_us or max_computations_us with probability
+	// max_computations_probability
+	std::uniform_real_distribution<float> distribution(0, 1);
+	float p = distribution(randGenerator);
+	return p >= max_computations_probability ? max_computations_us : computations_us;
+}
+
 auto main(int argc, char* argv[]) -> int {
 	std::string host = HOST;
 	std::string port = PORT;
 
-	if (argc > 4) {
-		std::cerr << "Usage: " << argv[0] << " [port] [computations_us] [max_computations_us]"
-							<< std::endl;
+	if (argc > 5) {
+		std::cerr << "Usage: " << argv[0] << " [port] [computations_us]"
+							<< " [max_computations_us] [max_computations_probability]" << std::endl;
 		exit(EXIT_FAILURE);
 	}
 
@@ -55,6 +76,12 @@ auto main(int argc, char* argv[]) -> int {
 			DIE_MSG("max_computations_us must be bigger than computations_us");
 	}
 
+	if (argc > 4) {
+		max_computations_probability = std::stof(argv[4]);
+		if (max_computations_probability < 0 || max_computations_probability > 1)
+			DIE_MSG("max_computations_probability must be in [0,1]");
+	}
+
 	std::cout << "Echoserver listening on " << host << ":" << port;
 	if (computations_us) {
 		std::cout << " with " << computations_us;
@@ -63,7 +90,13 @@ auto main(int argc, char* argv[]) -> int {
 	}
 	std::cout << std::endl;
 
-	Runtime runtime;
+	RuntimeBuilder runtimeBuilder;
+	if (max_computations_us) {
+		runtimeBuilder.newWorkerHook([](workerid_t id) { randGenerator.seed(id); });
+	}
+
+	auto runtime = runtimeBuilder.build();
+
 	auto serverFunc = [](int socket) {
 		// NOLINTNEXTLINE(modernize-avoid-c-arrays)
 		char buf[1024];
@@ -84,12 +117,7 @@ auto main(int argc, char* argv[]) -> int {
 			}
 
 			if (computations_us) {
-				unsigned int computation = computations_us;
-				if (max_computations_us) {
-					// Worker::rand is always positiv. Why does it return int?
-					computation += Worker::rand() % (max_computations_us - computations_us);
-				}
-
+				unsigned int computation = getComputation();
 				const auto start = std::chrono::steady_clock::now();
 				const auto deadline = start + std::chrono::microseconds(computation);
 				// TODO: The suppressed linter error below may be a false positive