diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..7895687
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,14 @@
+CC=g++
+CFLAGS=-Werror -Wall -Wextra -Ofast -pedantic
+
+all: build
+
+build:
+	$(CC) main.cpp -o httpsbench -lssl -lcrypto -lcurl -pthread $(CFLAGS)
+
+run: build
+	@echo "Usage: ./httpsbench -c <ThreadCount> -n <RequestCount> <URL>"
+	@echo "Example: ./httpsbench -c 10 -n 1000 http://example.com"
+	./httpsbench $(ARGS)
+
+.PHONY: all build run
\ No newline at end of file
diff --git a/README.md b/README.md
index 5c7fe3d..3b5148d 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,45 @@
-# httpsbench
+# HTTPS Benchmark Tool
 
-Application for benchmarking https servers 
\ No newline at end of file
+This tool is designed to benchmark HTTP requests using a thread pool for concurrent execution.
+
+## Usage
+
+To use the tool, compile and run it with the following commands:
+
+```bash
+make build
+./httpsbench -c <ThreadCount> -n <RequestCount> <URL>
+```
+
+### Example
+
+```bash
+./httpsbench -c 10 -n 1000 http://example.com
+```
+
+## Parameters
+
+- `-c <ThreadCount>`: Number of threads to use in the thread pool.
+- `-n <RequestCount>`: Number of HTTP requests to make.
+- `<URL>`: The URL to benchmark.
+
+## Output
+
+The tool will output the elapsed time in seconds and milliseconds, as well as the requests per second.
+
+## Dependencies
+
+- libcurl
+- libssl
+- libcrypto
+
+## Files
+
+- `main.cpp`: Main program file.
+- `threadpool.hpp`: Thread pool implementation.
+- `http.hpp`: HTTP request function declaration.
+- `Makefile`: Build script.
+
+## License
+
+This project is licensed under the MIT License - see the LICENSE.md file for details.
diff --git a/http.hpp b/http.hpp
new file mode 100644
index 0000000..8d8e2bc
--- /dev/null
+++ b/http.hpp
@@ -0,0 +1,50 @@
+#include <curl/curl.h>
+#include <stdio.h>
+
+
+// Callback function for handling data received from the server
+size_t write_callback(void *buffer, size_t size, size_t nmemb, void *userp) {
+    size_t total_size = size * nmemb;
+    fwrite(buffer, size, nmemb, (FILE *)userp);
+    return total_size;
+}
+
+void http_get(const char * url){
+    CURL *curl;
+    CURLcode res;
+ 
+    curl = curl_easy_init();
+
+    if (curl) {
+        // Set the URL for the request
+        curl_easy_setopt(curl, CURLOPT_URL, url);
+
+        // Use HTTPS
+        curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
+
+        // Verify the server's SSL certificate
+        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); // Enable SSL certificate verification
+        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L); // Verify that the certificate matches the hostname
+
+        // Optional: Specify CA certificate if the default is not sufficient
+        // curl_easy_setopt(curl, CURLOPT_CAINFO, "/path/to/cacert.pem");
+
+        // Set the write callback function to handle the response
+        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
+        curl_easy_setopt(curl, CURLOPT_WRITEDATA, stdout);
+
+        // Perform the request
+        res = curl_easy_perform(curl);
+
+        // Check for errors
+        if (res != CURLE_OK) {
+            fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
+        }
+
+        // Cleanup
+        curl_easy_cleanup(curl);
+    }
+
+}
+
+
diff --git a/httpsbench b/httpsbench
new file mode 100755
index 0000000..28cddaa
Binary files /dev/null and b/httpsbench differ
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..76a307b
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,82 @@
+#include <iostream>
+#include <vector>
+#include <thread>
+#include <queue>
+#include <functional>
+#include <condition_variable>
+#include "threadpool.hpp"
+#include "http.hpp"
+#include <chrono>
+
+std::mutex mtx;  // Mutex to protect shared data
+int threads_working = 0;
+
+// Function to simulate work that requires thread synchronization
+void incThreadsWorking() {
+    mtx.lock();  // Lock the mutex to enter the critical section
+    threads_working++;
+    mtx.unlock();  // Unlock the mutex to allow other threads to enter the critical section
+}
+void decThreadsWorking(){
+    mtx.lock();
+    threads_working--;
+    mtx.unlock();
+}
+
+int main(int argc, char* argv[]) {
+    const char* url = nullptr;
+    int threadCount = 10; // Default value
+    int requestCount = 1000; // Default value
+
+    // Parse command-line arguments
+    for (int i = 1; i < argc; ++i) {
+        if (std::string(argv[i]) == "-c" && i + 1 < argc) {
+            threadCount = std::stoi(argv[++i]);
+        } else if (std::string(argv[i]) == "-n" && i + 1 < argc) {
+            requestCount = std::stoi(argv[++i]);
+        } else {
+            url = argv[i]; // Assume the last argument is the URL
+        }
+    }
+
+    if (url == nullptr) {
+        std::cerr << "Usage: " << argv[0] << " -c <ThreadCount> -n <RequestCount> <URL>" << std::endl;
+        return 1;
+    }
+
+    // Initialize libcurl
+    curl_global_init(CURL_GLOBAL_DEFAULT);
+
+    auto start = std::chrono::steady_clock::now();
+
+    ThreadPool pool(threadCount);  // Create a pool with specified number of threads
+
+    // Submit tasks to the thread pool
+    for (int i = 0; i < requestCount; ++i) {
+        pool.enqueue([url, i] {
+            incThreadsWorking();
+            http_get(url);
+            decThreadsWorking();
+            std::cout << "Threads working: " << threads_working << std::endl;
+        });
+    }
+
+    while(threads_working){
+        std::this_thread::sleep_for(std::chrono::seconds(1));
+    }
+
+    auto end = std::chrono::steady_clock::now();
+    
+    auto duration = std::chrono::duration_cast<std::chrono::seconds>(end - start);
+    std::cout << "Elapsed time in seconds: " << duration.count() << " seconds." << std::endl;
+
+    auto duration_ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
+    std::cout << "Elapsed time in milliseconds: " << duration_ms.count() << " ms." << std::endl;
+
+    std::cout << "Requests per second: " << requestCount / duration.count() << "." << std::endl;
+
+    // Cleanup global libcurl state
+    curl_global_cleanup();
+
+    return 0;
+}
\ No newline at end of file
diff --git a/threadpool.hpp b/threadpool.hpp
new file mode 100644
index 0000000..5c290a0
--- /dev/null
+++ b/threadpool.hpp
@@ -0,0 +1,78 @@
+#include <iostream>
+#include <vector>
+#include <thread>
+#include <queue>
+#include <functional>
+#include <condition_variable>
+#include <atomic>
+
+class ThreadPool {
+public:
+    ThreadPool(size_t numThreads) : stop(false) {
+        for (size_t i = 0; i < numThreads; ++i) {
+            workers.emplace_back([this] {
+                while (true) {
+                    std::function<void()> task;
+
+                    // Lock the queue to retrieve the next task
+                    {
+                        std::unique_lock<std::mutex> lock(queueMutex);
+                        condition.wait(lock, [this] {
+                            return stop || !tasks.empty();
+                        });
+
+                        if (stop && tasks.empty()) {
+                            return;
+                        }
+
+                        // Get the next task from the queue
+                        task = std::move(tasks.front());
+                        tasks.pop();
+                    }
+
+                    // Execute the task
+                    task();
+                }
+            });
+        }
+    }
+
+    // Submit a task to the thread pool
+    template <typename F>
+    void enqueue(F&& f) {
+        {
+            std::unique_lock<std::mutex> lock(queueMutex);
+            if (stop) {
+                throw std::runtime_error("ThreadPool is stopped");
+            }
+            tasks.push(std::function<void()>(std::forward<F>(f)));
+        }
+        condition.notify_one();
+    }
+
+    // Wait for all threads to finish executing their tasks
+    void wait() {
+        // Block until all tasks have been completed
+        std::unique_lock<std::mutex> lock(queueMutex);
+        condition.wait(lock, [this] { return tasks.empty(); });
+    }
+
+    // Destructor: join all threads
+    ~ThreadPool() {
+        {
+            std::unique_lock<std::mutex> lock(queueMutex);
+            stop = true;
+        }
+        condition.notify_all();
+        for (std::thread& worker : workers) {
+            worker.join();  // Ensure each thread finishes before destruction
+        }
+    }
+
+private:
+    std::vector<std::thread> workers;
+    std::queue<std::function<void()>> tasks;
+    std::mutex queueMutex;
+    std::condition_variable condition;
+    bool stop;
+};