diff --git a/benchmark.sh b/benchmark.sh
new file mode 100755
index 0000000000000000000000000000000000000000..4da55304e55e440227efeb80e608b3af3f733676
--- /dev/null
+++ b/benchmark.sh
@@ -0,0 +1,10 @@
+#! /bin/bash
+for ((x=0; x < $1; x++))
+do
+time (
+	for ((y=0; y < $2; y++))
+	do
+		dig -t TXT ecklapos.sch.bme.hu @::1 -p 10053
+	done > /dev/null
+)&
+done
diff --git a/include/dns_server.h b/include/dns_server.h
index 98cf62b4a1475119c0ceedbde1c4113423e53a37..5abb7fd295310240ebf559d430ed93ccad272bb1 100644
--- a/include/dns_server.h
+++ b/include/dns_server.h
@@ -12,19 +12,21 @@
 #include "general_sockaddr_wp.h"
 #include "udp_socket_wp.h"
 
-class dns_server {
+class dns_server
+{
 private:
 	dns_db db;
 	udp_socket_wp socket;
-#ifndef DEBUG
+	volatile bool running; // Más jelentést kéne neki adni és akkor egyértelműbb lenne, hogy mikor kell beállítani igazra/hamisra
+	pthread_t *threads;
+	int thread_num;
+	dns_server(const dns_db& __db) { throw "Not implementable"; }
 protected:
-#else
-public:
-#endif
+	static void *thread_func(void *server_obj);
 	void serve_one_request();
+	void delete_threads();
 public:
-	dns_server() {}
-	dns_server(const dns_db& __db): db(__db) {}
+	dns_server();
 	dns_server(const general_sockaddr_wp& addr);
 	dns_server(const general_sockaddr_wp& addr, const char *db_path);
 	dns_server(const general_sockaddr_wp& addr, const dns_db& __db);
@@ -33,6 +35,11 @@ public:
 
 	void init(const general_sockaddr_wp& addr);
 
+	void serve_forever();
+	void serve_in_threads(int n);
+
+	void stop();
+
 	void shutdown();
 	virtual ~dns_server() { this->shutdown(); }
 };
diff --git a/include/exceptions/db_exception.h b/include/exceptions/db_exception.h
index fb75cb8c0c2ac3a47ff692bd05716f5bcee7230f..93de0e2e559e27d12a9eda917eda99b391338237 100644
--- a/include/exceptions/db_exception.h
+++ b/include/exceptions/db_exception.h
@@ -8,13 +8,14 @@
 #ifndef DB_EXCEPTION_H
 #define DB_EXCEPTION_H
 
+#include <string>
 #include <exception>
 
 class db_exception: public std::exception
 {
 	std::string msg;
 public:
-	db_exception(const std::string& msg): msg(msg) {}
+	explicit db_exception(const std::string& msg): msg(msg) {}
 	virtual const char *what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT { return msg.c_str(); }
 };
 
diff --git a/include/exceptions/dns_exception.h b/include/exceptions/dns_exception.h
index d7cf7e9c4a9b1910148196ead71deb8a37d4821b..0f8df4172f12bf6824eb5b1fa39100d4a35425ed 100644
--- a/include/exceptions/dns_exception.h
+++ b/include/exceptions/dns_exception.h
@@ -8,13 +8,14 @@
 #ifndef DNS_EXCEPTION_H
 #define DNS_EXCEPTION_H
 
+#include <string>
 #include <exception>
 
 class dns_exception: public std::exception
 {
 	std::string msg;
 public:
-	dns_exception(const std::string& msg): msg(msg) {}
+	explicit dns_exception(const std::string& msg): msg(msg) {}
 	virtual const char *what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT { return msg.c_str(); }
 };
 
diff --git a/include/exceptions/server_error.h b/include/exceptions/server_error.h
new file mode 100644
index 0000000000000000000000000000000000000000..9de8960b93db0d2811bac4a52e6d7fd9df13a5eb
--- /dev/null
+++ b/include/exceptions/server_error.h
@@ -0,0 +1,20 @@
+/* 
+ * File:   server_error.h
+ * Author: Eckl Máté <ecklm94@gmail.com>
+ *
+ * Created on 2016. május 22., 22:23
+ */
+
+#ifndef SERVER_ERROR_H
+#define SERVER_ERROR_H
+
+#include <string>
+#include <stdexcept>
+
+class server_error: public std::runtime_error
+{
+public:
+	explicit server_error(const std::string& msg): std::runtime_error(msg) {}
+};
+
+#endif /* SERVER_ERROR_H */
diff --git a/main.cpp b/main.cpp
index a6a95d849ded81a64db840de304b8eadf7767fb5..3b6681a8bab71647f2c0764d469d87f02b227edd 100644
--- a/main.cpp
+++ b/main.cpp
@@ -72,11 +72,7 @@ int main(int argc, char *argv[])
 	{
 		openlog("ecklm-dns", LOG_PID, LOG_DAEMON);
 		log_on_demand = syslog_on_demand;
-#ifdef DEBUG // ezt az egész mókát parancssori paraméterektől kell majd függővé tenni
-		if(daemon(0,1) < 0)
-#else
 		if(daemon(0,0) < 0)
-#endif
 		{
 			PERROR_ON_DEMAND("daemon");
 			exit(EXIT_FAILURE);
@@ -164,14 +160,17 @@ int main(int argc, char *argv[])
 // ----------------- INIT END --------------------------
 
 // ------------------ SERVE ----------------------------
-	while(true)
+	int thread_num = 8;
+	server.serve_in_threads(thread_num);
+	bool stop = false;
+	while(!stop)
 	{
-		server.serve_one_request();
 		if(comm_link.recv_data() == "kill")
 		{
 			comm_link.send_data("go to hell!");
-			log_on_demand(LOG_DEBUG, "Raising SIGTERM");
-			raise(SIGTERM);
+			stop = true;
+			log_on_demand(LOG_DEBUG, "Raising SIGPIPE");
+			raise(SIGPIPE);
 		}
 		else
 			comm_link.send_data("nothing has happened");
@@ -181,6 +180,7 @@ int main(int argc, char *argv[])
 // ------------------- SHUTDOWN -------------------------
 	server.shutdown();
 // ----------------- SHUTDOWN END -----------------------
+	log_on_demand(LOG_INFO, "Server just exited.");
 	exit(EXIT_SUCCESS);
 }
 
diff --git a/measurement.md b/measurement.md
new file mode 100644
index 0000000000000000000000000000000000000000..998c89bbc4563dea5f52bc8372ce4a5ba31c5fb8
--- /dev/null
+++ b/measurement.md
@@ -0,0 +1,216 @@
+# Körülmények
+
+A mérést végző szkript bash, ami a legkevésbé sem hatékony, úgyhogy az időkbe bele kell venni az interpretálást és egyéb bash lassúságát okozó tényezőket is.
+
+# 1 thread vs. 8*500 kérés, Debug:
+
+	real    0m30.662s
+	user    0m6.947s
+	sys     0m2.273s
+
+	real    0m30.817s
+	user    0m7.043s
+	sys     0m2.223s
+
+	real    0m30.856s
+	user    0m6.967s
+	sys     0m2.287s
+
+	real    0m30.911s
+	user    0m7.013s
+	sys     0m2.233s
+
+	real    0m30.918s
+	user    0m7.117s
+	sys     0m2.177s
+
+	real    0m31.146s
+	user    0m7.107s
+	sys     0m2.157s
+
+	real    0m31.249s
+	user    0m7.183s
+	sys     0m2.083s
+
+	real    0m31.239s
+	user    0m7.163s
+	sys     0m2.157s
+
+# 1 thread vs. 8*500 kérés, Release:
+
+	real    0m21.074s
+	user    0m6.803s
+	sys     0m2.020s
+
+	real    0m21.156s
+	user    0m6.737s
+	sys     0m2.117s
+
+	real    0m21.178s
+	user    0m6.900s
+	sys     0m1.900s
+
+	real    0m21.311s
+	user    0m6.807s
+	sys     0m2.000s
+
+	real    0m21.342s
+	user    0m6.820s
+	sys     0m2.043s
+
+	real    0m21.344s
+	user    0m6.793s
+	sys     0m2.060s
+
+	real    0m21.350s
+	user    0m6.750s
+	sys     0m2.047s
+
+	real    0m21.371s
+	user    0m6.777s
+	sys     0m2.010s
+
+# 4 thread vs. 8*500 kérés, Debug:
+
+	real    0m28.167s
+	user    0m7.060s
+	sys     0m2.083s
+
+	real    0m28.582s
+	user    0m6.973s
+	sys     0m2.177s
+
+	real    0m28.598s
+	user    0m7.070s
+	sys     0m2.130s
+
+	real    0m28.608s
+	user    0m7.027s
+	sys     0m2.123s
+
+	real    0m30.697s
+	user    0m7.090s
+	sys     0m2.080s
+
+	real    0m30.829s
+	user    0m7.023s
+	sys     0m2.100s
+
+	real    0m32.545s
+	user    0m6.950s
+	sys     0m2.247s
+
+	real    0m35.482s
+	user    0m6.967s
+	sys     0m2.140s
+
+# 4 thread vs. 8*500 kérés, Release:
+
+	real    0m16.877s
+	user    0m6.647s
+	sys     0m2.253s
+
+	real    0m22.030s
+	user    0m6.647s
+	sys     0m2.187s
+
+	real    0m22.047s
+	user    0m6.790s
+	sys     0m2.050s
+
+	real    0m22.144s
+	user    0m6.783s
+	sys     0m2.037s
+
+	real    0m31.346s
+	user    0m6.707s
+	sys     0m2.457s
+
+	real    0m31.670s
+	user    0m6.623s
+	sys     0m2.393s
+
+	real    0m32.054s
+	user    0m6.687s
+	sys     0m2.250s
+
+	real    0m36.725s
+	user    0m6.783s
+	sys     0m2.230s
+
+# 8 thread vs. 8*500 kérés, Debug:
+
+	real    0m22.967s
+	user    0m6.930s
+	sys     0m2.090s
+
+	real    0m23.015s
+	user    0m7.070s
+	sys     0m1.960s
+
+	real    0m23.362s
+	user    0m7.010s
+	sys     0m2.077s
+
+	real    0m26.676s
+	user    0m6.780s
+	sys     0m2.170s
+
+	real    0m26.979s
+	user    0m6.807s
+	sys     0m2.220s
+
+	real    0m29.270s
+	user    0m6.957s
+	sys     0m2.097s
+
+	real    0m30.313s
+	user    0m6.740s
+	sys     0m2.250s
+
+	real    0m36.571s
+	user    0m6.827s
+	sys     0m2.140s
+
+# 8 thread vs. 8*500 kérés, Release:
+
+Itt mer előjöttek szálkezeléssel kapcsolatos problémák.
+Mivel a static lokális változók a heap-en allokálódnak, így több szál is írhatta egyszerre a dns_db::ger_record()-ban a query tömböt. Emiatt romlottak el a végső lekérdezések.
+
+> SQL error: near "select": syntax error
+
+> SQL error: near "select": syntax error
+
+> SQL error: unrecognized token: "s"
+
+	real    0m16.450s
+	user    0m6.677s
+	sys     0m2.140s
+
+	real    0m21.445s
+	user    0m6.643s
+	sys     0m2.230s
+
+	real    0m25.883s
+	user    0m6.757s
+	sys     0m2.163s
+
+	real    0m26.116s
+	user    0m6.810s
+	sys     0m2.073s
+
+	real    0m26.525s
+	user    0m6.673s
+	sys     0m2.193s
+
+	real    0m26.573s
+	user    0m6.660s
+	sys     0m2.127s
+
+	real    0m31.140s
+	user    0m6.757s
+	sys     0m2.437s
+
+	real    0m31.485s
+	user    0m6.867s
+	sys     0m2.037s
diff --git a/nbproject/Makefile-Debug.mk b/nbproject/Makefile-Debug.mk
index 910c1d64ffc941e4f6221ce138e3ec39e23029ba..39773f9bf6669903d679d5f5af758563a4b403fc 100644
--- a/nbproject/Makefile-Debug.mk
+++ b/nbproject/Makefile-Debug.mk
@@ -53,8 +53,8 @@ OBJECTFILES= \
 CFLAGS=
 
 # CC Compiler Flags
-CCFLAGS=-lsqlite3
-CXXFLAGS=-lsqlite3
+CCFLAGS=-lsqlite3 -pthread
+CXXFLAGS=-lsqlite3 -pthread
 
 # Fortran Compiler Flags
 FFLAGS=
diff --git a/nbproject/Makefile-Release.mk b/nbproject/Makefile-Release.mk
index 73b1f9bdfdd6be88c938bbbafd70540fe11f1910..566495d8e2ca93382331c79800352147d26efc30 100644
--- a/nbproject/Makefile-Release.mk
+++ b/nbproject/Makefile-Release.mk
@@ -53,8 +53,8 @@ OBJECTFILES= \
 CFLAGS=
 
 # CC Compiler Flags
-CCFLAGS=-lsqlite3
-CXXFLAGS=-lsqlite3
+CCFLAGS=-lsqlite3 -pthread
+CXXFLAGS=-lsqlite3 -pthread
 
 # Fortran Compiler Flags
 FFLAGS=
diff --git a/src/dns_db.cpp b/src/dns_db.cpp
index 9610d4d0693c1386b5eb477f8498867f004f0630..82c55253987f7d5c4a5facbffca151c9ce7466f0 100644
--- a/src/dns_db.cpp
+++ b/src/dns_db.cpp
@@ -13,6 +13,7 @@
 
 #include <string.h>
 #include <string>
+#include <pthread.h>
 
 extern logger log_on_demand;
 extern bool verbose;
@@ -92,6 +93,7 @@ static int callback(void *param, int argc, char **argv, char **azColName) {
 	ret->ttl = atoi(argv[3]);
 	if(verbose)
 	{
+		log_on_demand(LOG_DEBUG, "Called in thread %lu\n", pthread_self());
 		log_on_demand(LOG_DEBUG, "Database hit:");
 		for(int i=0;i<argc;i++)
 			log_on_demand(LOG_DEBUG, "%s = %s", azColName[i], argv[i]);
@@ -106,7 +108,7 @@ record dns_db::get_record(dns_question question) {
 	}
 	static const char *query_format_string =
 		"select name, type, content, ttl from records where name='%s' and type='%s' limit 1";
-	static char query[500];
+	char query[500];
 	record query_result;
 
 	char readable_name[500];
diff --git a/src/dns_server.cpp b/src/dns_server.cpp
index 52bfdc0983ab16862bcca7f1a1b66d2103c96283..fbcc13b4ffc98fedd7f2787828209b2295375c94 100644
--- a/src/dns_server.cpp
+++ b/src/dns_server.cpp
@@ -5,37 +5,70 @@
  * Created on 2016. május 21., 18:47
  */
 
+#include <pthread.h>
+
 #include "../include/dns_server.h"
 #include "../include/dns_types.h"
 #include "../include/exceptions/db_exception.h"
 #include "../include/exceptions/dns_exception.h"
 #include "../include/logger.h"
+#include "../include/exceptions/server_error.h"
 
+pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+		
 extern logger log_on_demand;
 extern bool verbose;
 
-dns_server::dns_server(const general_sockaddr_wp& addr) {
+dns_server::dns_server(): running(false), threads(NULL), thread_num(0) { }
+
+dns_server::dns_server(const general_sockaddr_wp& addr): running(false), threads(NULL), thread_num(0) {
 	init(addr);
 }
 
-dns_server::dns_server(const general_sockaddr_wp& addr, const char *db_path) {
+dns_server::dns_server(const general_sockaddr_wp& addr, const char *db_path): running(false), threads(NULL), thread_num(0) {
 	init(addr);
 	connect_db(db_path);
 }
 
-dns_server::dns_server(const general_sockaddr_wp& addr, const dns_db& __db): db(__db) {
+dns_server::dns_server(const general_sockaddr_wp& addr, const dns_db& __db): db(__db), running(false), threads(NULL), thread_num(0) {
 	init(addr);
 }
 
 void dns_server::init(const general_sockaddr_wp& addr) {
+	pthread_mutex_lock(&mutex);
 	this->socket.close_socket(); // in case it's being changed
 	this->socket.set_domain(addr.get_sockaddr()->sa_family);
 	this->socket.bind_wp(addr);
+	running = true;
+	pthread_mutex_unlock(&mutex);
+}
+
+void dns_server::delete_threads() {
+	pthread_mutex_lock(&mutex);
+	if(threads != NULL)
+	{
+		delete[] threads;
+		threads = NULL;
+	}
+	thread_num = 0;
+	pthread_mutex_unlock(&mutex);
+}
+
+void dns_server::stop() {
+	pthread_mutex_lock(&mutex);
+	running = false;
+	pthread_mutex_unlock(&mutex);
+	for(int i=0; i<thread_num; i++)
+		pthread_join(threads[i], NULL);
+	delete_threads();
 }
 
 void dns_server::shutdown() {
+	stop();
+	pthread_mutex_lock(&mutex);
 	this->socket.close_socket();
 	db.close();
+	pthread_mutex_unlock(&mutex);
 }
 
 void dns_server::serve_one_request() {
@@ -50,7 +83,7 @@ void dns_server::serve_one_request() {
 		query.set_response();
 		query.set_error(ex.what());
 		this->socket.sendto_wp(query, 0 , (sockaddr*)&sender, slen);
-		exit(EXIT_SUCCESS);
+		return;
 	}
 
 	if(verbose)
@@ -84,3 +117,51 @@ void dns_server::serve_one_request() {
 
 	this->socket.sendto_wp(resp, 0, (sockaddr*) &sender, slen);
 }
+
+void dns_server::serve_forever() {
+	while (running)
+	{
+		serve_one_request();
+	}
+}
+
+void* dns_server::thread_func(void* server_obj) {
+	dns_server *server = (dns_server*) server_obj;
+	server->serve_forever();
+	return NULL;
+}
+
+void dns_server::serve_in_threads(int n) {
+	pthread_mutex_lock(&mutex);
+	try {
+		if(threads != NULL)
+		{
+			throw server_error("Threads are already running");
+		}
+		thread_num = n;
+		threads = new pthread_t[thread_num];
+	}
+	catch(...) {
+		pthread_mutex_unlock(&mutex);
+		throw;
+	}
+	pthread_mutex_unlock(&mutex);
+
+	try {
+		pthread_mutex_lock(&mutex);
+		for(int i=0; i<thread_num; i++)
+		{
+			if (pthread_create(&threads[i], NULL, thread_func, this)) {
+				fprintf(stderr, "Hiba a szál Létrehozásakor.\n");
+				// May throw some exception...
+				exit(EXIT_FAILURE);
+			}
+		}
+		pthread_mutex_unlock(&mutex);
+	}
+	catch (...) {
+		pthread_mutex_unlock(&mutex);
+		stop();
+		throw;
+	}
+}