diff --git a/prak3/.vscode/launch.json b/prak3/.vscode/launch.json
index 2ad16e4c7ad14d5b1d4ab77d0419db2186392707..e40495c38db351f015684020e8a638756617b4cc 100644
--- a/prak3/.vscode/launch.json
+++ b/prak3/.vscode/launch.json
@@ -37,11 +37,68 @@
             "preLaunchTask": "build"
         },
         {
-            "name": "Debug Client",
+            "name": "Debug Client (equal)",
             "type": "cppdbg",
             "request": "launch",
             "program": "${workspaceFolder}/build/src/myclient",
             "args": [
+                "127.0.0.1",
+                "2525",
+                "1024",
+                "20000",
+                "equal",
+            ],
+            "stopAtEntry": false,
+            "cwd": "${workspaceFolder}",
+            "environment": [],
+            "externalConsole": false,
+            "MIMode": "gdb",
+            "setupCommands": [
+                {
+                    "description": "Enable pretty-printing for gdb",
+                    "text": "-enable-pretty-printing",
+                    "ignoreFailures": true
+                }
+            ],
+            "preLaunchTask": "build"
+        },
+        {
+            "name": "Debug Client (random)",
+            "type": "cppdbg",
+            "request": "launch",
+            "program": "${workspaceFolder}/build/src/myclient",
+            "args": [
+                "127.0.0.1",
+                "2525",
+                "1024",
+                "20000",
+                "random",
+            ],
+            "stopAtEntry": false,
+            "cwd": "${workspaceFolder}",
+            "environment": [],
+            "externalConsole": false,
+            "MIMode": "gdb",
+            "setupCommands": [
+                {
+                    "description": "Enable pretty-printing for gdb",
+                    "text": "-enable-pretty-printing",
+                    "ignoreFailures": true
+                }
+            ],
+            "preLaunchTask": "build"
+        },
+        {
+            "name": "Debug Client (realistic)",
+            "type": "cppdbg",
+            "request": "launch",
+            "program": "${workspaceFolder}/build/src/myclient",
+            "args": [
+                "127.0.0.1",
+                "2525",
+                "1024",
+                "20000",
+                "realistic",
             ],
             "stopAtEntry": false,
             "cwd": "${workspaceFolder}",
diff --git a/prak3/readme.md b/prak3/readme.md
index 17aace96aaf2fb10ed0bca98400f89237bbc1a4e..6457039d8074844552c7df7c007f73ed2bb7f0d2 100644
--- a/prak3/readme.md
+++ b/prak3/readme.md
@@ -21,35 +21,32 @@ Use the following command to execute the server:
 ```
 Use the following command to execute the client:
 ```sh
-./build/src/myclient store name saif
-./build/src/myclient store name chris
-./build/src/myclient get name 
-./build/src/myclient delete name 
-./build/src/myclient get name 
+./startClients.sh <SERVER_IP> <PORT> <BUFFER_SIZE> <NUMBER_OF_REQUESTS> <REQUEST_GENERATION_TYPE>
 ```
 
 ---
 
 
-## 🛠 Performance Testing (EDIT THIT )
+## 🛠 Performance Testing
 
 The following scripts measure execution time and generate profiling data for different scenarios:
 
 ### ⏳ Execution Time Measurement
 
-- **With socket output:**  
+- **Execute the client with random Requests:**  
   ```sh
-  ./exec_time.sh socket
+  ./startClients.sh 141.100.42.131 2525 1024 2000 random
   ```
-- **With pipe output:**  
+- **Execute the client with equal Requests:**  
   ```sh
-  ./exec_time.sh pipe
+  ./startClients.sh 141.100.42.131 2525 1024 2000 equal
   ```
-- **With shared_memory output:**  
+- **Execute the client with realistic Requests:**  
   ```sh
-  ./exec_time.sh shared_memory
+  ./startClients.sh 141.100.42.131 2525 1024 2000 realistic
   ```
 
+
 ### đŸ”„ Stack Trace & Profiling (Perf + Flamegraphs)
 
 - **With socket output:**  
diff --git a/prak3/src/client.cpp b/prak3/src/client.cpp
index 7f648276bc1247e1eb161d09249bfbb61842dc35..8d82c4f8750fc1b154c3769f38f4efb12850bf85 100644
--- a/prak3/src/client.cpp
+++ b/prak3/src/client.cpp
@@ -6,15 +6,13 @@
 #include <cstdlib>
 #include <ctime>
 
-#define SERVER_IP "127.0.0.1"
-#define PORT 2525
-#define BUFFER_SIZE 1024
-#define REQUEST_COUNT 70000
+pid_t pid = getpid();
 
 std::string generateRandomKey() {
-    return "key" + std::to_string(rand() % 1000);
+    return "key" + std::to_string(rand() % 100);
 }
 
+
 std::string generateRandomValue() {
     return "value" + std::to_string(rand() % 10000);
 }
@@ -31,44 +29,102 @@ std::string createRandomMessage() {
     }
 }
 
-int main() {
+std::vector<std::string> generateRequests(int requestCount, std::string requestGenerationType) {
+    std::vector<std::string> requests;
+    requests.reserve(requestCount);
+    
+    if (requestGenerationType == "random") {
+        for (int i = 0; i < requestCount; i++) {
+            requests.push_back(createRandomMessage());
+        }
+    } else if (requestGenerationType == "equal") {
+        int getCount = requestCount * 0.33;
+        int storeCount = requestCount * 0.33;
+        int deleteCount = requestCount * 0.33;
+
+        for (int i = 0; i < getCount; i++) {
+            requests.push_back("s,key" + std::to_string(pid) + std::to_string(i) + ",value" + std::to_string(i) + ";");
+        }
+        for (int i = 0; i < storeCount; i++) {
+            requests.push_back("g,key" + std::to_string(pid) + std::to_string(i) +';');
+        }
+        for (int i = 0; i < deleteCount; i++) {
+            requests.push_back("d,key" + std::to_string(pid) + std::to_string(i)  + ';');
+        }
+    } else if (requestGenerationType == "realistic") {
+        int getCount = requestCount * 0.7;
+        int storeCount = requestCount * 0.25;
+        int deleteCount = requestCount - (getCount + storeCount); // Restliche 5%
+
+        for (int i = 0; i < getCount; i++) {
+            requests.push_back("g," + generateRandomKey() + ";");
+        }
+        for (int i = 0; i < storeCount; i++) {
+            requests.push_back("s," + generateRandomKey() + "," + generateRandomValue() + ";");
+        }
+        for (int i = 0; i < deleteCount; i++) {
+            requests.push_back("d," + generateRandomKey() + ";");
+        }
+
+        // Um eine realistischere Last zu simulieren, die Reihenfolge zufÀllig mischen
+        //std::random_shuffle(requests.begin(), requests.end());
+    } else {
+        std::cerr << "requestGenerationType is not expected. Please use [random, equal, realistic]" << std::endl;
+    }
+    return requests;
+}
+
+
+int main(int argc, char* argv[]) {
+    if (argc != 6) {
+        std::cerr << "Usage: " << argv[0] << " <server_ip> <port> <buffer_size> <request_count> <requestGenerationType [random, equal, realistic]>" << std::endl;
+        return EXIT_FAILURE;
+    }
+
+    std::string serverIp = argv[1];
+    int port = std::stoi(argv[2]);
+    int bufferSize = std::stoi(argv[3]);
+    int requestCount = std::stoi(argv[4]);
+    std::string requestGenerationType = argv[5];
+
     srand(time(nullptr));
 
+    std::vector<std::string> requests = generateRequests(requestCount, requestGenerationType);
+
     int sock;
     struct sockaddr_in server_address;
-    char buffer[BUFFER_SIZE] = {0};
+    char* buffer[bufferSize] = {0};
 
     // Socket erstellen
     sock = socket(AF_INET, SOCK_STREAM, 0);
     if (sock == -1) {
         perror("Socket failed");
-        exit(EXIT_FAILURE);
+        return EXIT_FAILURE;
     }
 
     // Serveradresse konfigurieren
     server_address.sin_family = AF_INET;
-    server_address.sin_port = htons(PORT);
-    if (inet_pton(AF_INET, SERVER_IP, &server_address.sin_addr) <= 0) {
+    server_address.sin_port = htons(port);
+    if (inet_pton(AF_INET, serverIp.c_str(), &server_address.sin_addr) <= 0) {
         perror("Invalid address");
-        exit(EXIT_FAILURE);
+        return EXIT_FAILURE;
     }
 
     // Verbindung zum Server herstellen
     if (connect(sock, (struct sockaddr*)&server_address, sizeof(server_address)) < 0) {
         perror("Connection failed");
-        exit(EXIT_FAILURE);
+        return EXIT_FAILURE;
     }
 
-    for (int i = 0; i < REQUEST_COUNT; i++) {
-        std::string message = createRandomMessage();
+    for (const auto& message : requests) {
         send(sock, message.c_str(), message.size(), 0);
         std::cout << "Sent: " << message << std::endl;
 
-        ssize_t bytes_received = read(sock, buffer, BUFFER_SIZE);
+        ssize_t bytes_received = read(sock, buffer, bufferSize);
         if (bytes_received > 0) {
-            std::cout << "Server: " << buffer << std::endl;
+            std::cout << "Server Response: " << buffer << std::endl;
         }
-        memset(buffer, 0, BUFFER_SIZE);
+        memset(buffer, 0, bufferSize);
     }
 
     std::cout << "Closing connection..." << std::endl;
diff --git a/prak3/src/server.cpp b/prak3/src/server.cpp
index b83f9c263041ef4c85deff4af950af6c1526b274..e2198f50c8e10df646b700a5636124e1602bcb70 100644
--- a/prak3/src/server.cpp
+++ b/prak3/src/server.cpp
@@ -6,6 +6,7 @@
 #include <arpa/inet.h>
 #include <mutex>
 #include <map>
+#include <atomic>
 
 #define PORT 2525
 #define BUFFER_SIZE 1024
@@ -13,89 +14,18 @@
 #define GET_OPERATION 'g'
 #define DELETE_OPERATION 'd'
 
-//=========== SLOW PARSER ====================
-struct Request {
-    char operation;         
-    std::string key;      
-    std::string value;
-};
- Request* parseRequest(const char* buffer) {
-    // Create a new Request struct
-    Request* req = new Request();
-
-    // Copy the input buffer to a mutable string for tokenization
-    char* input = strdup(buffer); // Duplicate the buffer
-    if (!input) {
-        return nullptr; // Handle memory allocation failure
-    }
-
-    // Tokenize the input string using ',' and ';' as delimiters
-    char* token = strtok(input, ",;");
-    if (token) {
-        // First token is the operation
-        req->operation = token[0]; // Extract the first character (s, g, or d)
-
-        // Second token is the key
-        token = strtok(nullptr, ",;");
-        if (token) {
-            req->key = token;
-
-            // Third token is the value (only for store operation)
-            if (req->operation == 's') {
-                token = strtok(nullptr, ",;");
-                if (token) {
-                    req->value = token;
-                }
-            }
-        }
-    }
-
-    // Free the duplicated input string
-    free(input);
-
-    return req;
-}
-//=============================================
-
 std::mutex mtx;
 std::map<std::string, std::string> DB;
+std::atomic<int> request_count(0);
 
-// we assume that this function is slow
-std::string processRequest_slow(const std::string& request) {
-
-    std::string response;   
-    Request* parsedRequest = parseRequest(request.c_str());
-
-    std::lock_guard<std::mutex> lock(mtx);
-
-    switch (parsedRequest->operation) {
-        case STORE_OPERATION:
-            DB[parsedRequest->key] = parsedRequest->value;
-            response = "Stored [" + parsedRequest->key + "] = " + parsedRequest->value;
-            break;
-        case GET_OPERATION:
-            if (DB.find(parsedRequest->key) != DB.end()) {
-                response = "Value of [" + parsedRequest->key + "] is " + DB[parsedRequest->key];
-            } else {
-                response = "Key [" + parsedRequest->key + "] not found";
-            }
-            break;
-        case DELETE_OPERATION:
-            if (DB.erase(parsedRequest->key)) {
-                response = "Deleted key [" + parsedRequest->key + "]";
-            } else {
-                response = "Key [" + parsedRequest->key + "] not found for deletion";
-            }
-            break;
-        default:
-            response = "Invalid operation!";
-            break;
+void throughput_monitor() {
+    while (true) {
+        std::this_thread::sleep_for(std::chrono::seconds(1));
+        std::cout << "Anfragen pro Sekunde: " << request_count.load() << std::endl;
+        request_count.store(0);
     }
-
-    return response;
 }
-    
-// there is parsing problem the parced key is always with ; at the end
+
 std::string processRequest(const std::string& request) {
     std::string response;
 
@@ -112,11 +42,9 @@ std::string processRequest(const std::string& request) {
     std::string value;
 
     if (second != std::string::npos) {
-        // Extract key without ';'
         key = request.substr(first + 1, second - first - 1);
         value = request.substr(second + 1, end - second - 1);
     } else {
-        // Extract key correctly without including ';'
         key = request.substr(first + 1, end - first - 1);
     }
 
@@ -151,20 +79,21 @@ std::string processRequest(const std::string& request) {
 
 void handle_client(int client_socket) {
     char buffer[BUFFER_SIZE] = {0};
-
-    while (true) { // the Thread is allways active
+    while (true) {
         ssize_t bytes_received = read(client_socket, buffer, BUFFER_SIZE - 1);
         if (bytes_received <= 0) {
             std::cout << "Client disconnected." << std::endl;
             break;
         }
-        
+
         buffer[bytes_received] = '\0';
         std::string response = processRequest(buffer);
         
+        // AnfragezÀhler inkrementieren
+        request_count.fetch_add(1, std::memory_order_relaxed);
+
         send(client_socket, response.c_str(), response.size(), 0);
     }
-
     close(client_socket);
 }
 
@@ -195,6 +124,10 @@ int main() {
 
     std::cout << "Server listening on port " << PORT << std::endl;
 
+    // Starte den Throughput-Monitor
+    std::thread monitor_thread(throughput_monitor);
+    monitor_thread.detach();
+
     while (true) {
         client_socket = accept(server_fd, (struct sockaddr*)&address, &addrlen);
         
diff --git a/prak3/startClients.sh b/prak3/startClients.sh
new file mode 100644
index 0000000000000000000000000000000000000000..b7ab5b8e6a1c6fcbbdd7862de56d0ee16b817b82
--- /dev/null
+++ b/prak3/startClients.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+# Configuration
+PROCESS="./build/src/myclient"  # Path to the process/script you want to run
+SERVER_IP=$1                    # Server IP (first argument)
+PORT=$2                         # Port (second argument)
+BUFFER_SIZE=$3                  # Buffer size (third argument)
+NUMBER_OF_REQUESTS=$4           # Number of requests (fourth argument)
+REQUEST_GENERATION_TYPE=$5      # Request generation type (fifth argument)
+NUMBER_OF_PROCESSES_TO_START = $6
+
+# Validate input arguments
+if [ $# -ne 6 ]; then
+    echo "Usage: $0 <SERVER_IP> <PORT> <BUFFER_SIZE> <NUMBER_OF_REQUESTS> <REQUEST_GENERATION_TYPE>"
+    exit 1
+fi
+
+# Function to run the process
+run_process() {
+    local id=$1
+    echo "Starting process $id with args: $SERVER_IP, $PORT, $BUFFER_SIZE, $REQUEST_GENERATION_TYPE"
+    $PROCESS "$SERVER_IP" "$PORT" "$BUFFER_SIZE" "$NUMBER_OF_REQUESTS" "$REQUEST_GENERATION_TYPE" > "output_$id.log" 2>&1
+    echo "Finished process $id"
+}
+
+# Parallel execution
+echo "Running $NUMBER_OF_PROCESSES_TO_START processes in parallel..."
+for ((i = 1; i <= NUMBER_OF_PROCESSES_TO_START; i++)); do
+    run_process $i &
+done
+wait # Wait for all background processes to finish
+
+echo "All processes completed."
\ No newline at end of file