diff --git a/apps/EchoClient.cpp b/apps/EchoClient.cpp
index 830d23bbcf3f329f9801a715357922b4edd4f604..ae9a8dcd3a08575a446ca04ca1f98dbc173545a6 100644
--- a/apps/EchoClient.cpp
+++ b/apps/EchoClient.cpp
@@ -409,34 +409,18 @@ auto main(int argc, char* argv[]) -> int {
 
 		auto echo_end = high_resolution_clock::now();
 
-		RunningAverage avg_ns;
-		RunningAverage avg_iterations;
-		uint64_t total_iterations = 0;
-		uint64_t reconnects = 0;
-		uint64_t unexpectedEchos = 0;
-		for (size_t i = 0; i < nclients; ++i) {
-			avg_ns.update(clients[i]->avg_ns.getAverage());
-			avg_iterations.update(clients[i]->iteration);
-			total_iterations += clients[i]->iteration;
-			unexpectedEchos += clients[i]->unexpectedEchos;
-			reconnects += clients[i]->reconnects;
-		}
-
 		auto connect_duration = duration_cast<nanoseconds>(echo_start - connect_start).count();
 		auto echo_duration = duration_cast<nanoseconds>(echo_end - echo_start).count();
 		auto total_duration = duration_cast<nanoseconds>(echo_end - connect_start).count();
 
-		bool exists = true;
 		if (output_file) {
-			exists = access(output_file, W_OK) == 0;
-			int openflags;
-			int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
-			if (!exists) {
-				openflags = O_CREAT | O_WRONLY;
-			} else {
-				openflags = O_APPEND;
+			if (access(output_file, W_OK) == 0) {
+				DIE_MSG("Output file: " << output_file << " already exists");
 			}
 
+			int openflags = O_CREAT | O_WRONLY;
+			int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
+
 			out_fd = emper::io::openAndWait(output_file, openflags, mode);
 			if (out_fd < 0) {
 				DIE_MSG_ERRNO("opening output file failed");
@@ -444,14 +428,24 @@ auto main(int argc, char* argv[]) -> int {
 		}
 
 		std::stringstream sst;
-		if (!exists) {
-			sst << "clients,iterations,total_iterations,size,avg_ns,reconnects,unexpected_echos,connect,"
-						 "echo,total"
-					<< std::endl;
+		sst << "[global]" << std::endl;
+		sst << "clients = " << nclients << std::endl;
+		sst << "size = " << size << std::endl;
+		sst << "connect_duration = " << connect_duration << std::endl;
+		sst << "echo_duration = " << echo_duration << std::endl;
+		sst << "total_duration = " << total_duration << std::endl;
+		sst << std::endl;
+
+		sst << "[clients]" << std::endl;
+		sst << "csv =" << std::endl;
+		sst << " iterations,avg_ns,reconnects,unexpected_echos" << std::endl;
+		for (size_t i = 0; i < nclients; ++i) {
+			auto* client = clients[i];
+			sst << " " << client->iteration << ",";
+			sst << client->avg_ns.getAverage() << ",";
+			sst << client->reconnects << ",";
+			sst << client->unexpectedEchos << std::endl;
 		}
-		sst << nclients << "," << avg_iterations.getAverage() << "," << total_iterations << "," << size
-				<< "," << avg_ns.getAverage() << "," << reconnects << "," << unexpectedEchos << ","
-				<< connect_duration << "," << echo_duration << "," << total_duration << std::endl;
 
 		auto output = sst.str();
 		if (emper::io::writeFileAndWait(out_fd, output.c_str(), output.size()) < 0) {