diff --git a/Knot.files b/Knot.files
index 315e42c2d5a5b1fd421b3af34821eadf98172854..d370f89c6ea626729627aba86200014e7a98693b 100644
--- a/Knot.files
+++ b/Knot.files
@@ -129,6 +129,8 @@ src/knot/server/tcp-handler.c
 src/knot/server/tcp-handler.h
 src/knot/server/udp-handler.c
 src/knot/server/udp-handler.h
+src/knot/server/zones.c
+src/knot/server/zones.h
 src/knot/ctl/process.c
 src/knot/ctl/process.h
 src/knot/conf/cf-lex.l
diff --git a/src/dnslib/zonedb.c b/src/dnslib/zonedb.c
index f97782ae505053846b3bc5642c2033b811ac0dbd..2a2f2e0e2df3bdc2d6f7e1dd9cd58f03ad2176f7 100644
--- a/src/dnslib/zonedb.c
+++ b/src/dnslib/zonedb.c
@@ -165,6 +165,10 @@ void dnslib_zonedb_free(dnslib_zonedb_t **db)
 
 void dnslib_zonedb_deep_free(dnslib_zonedb_t **db)
 {
+	debug_dnslib_zonedb("Deleting zone db (%p).\n", *db);
+	debug_dnslib_zonedb("Is it empty (%p)? %s\n",
+	       (*db)->zones, skip_is_empty((*db)->zones) ? "yes" : "no");
+
 	const skip_node_t *zn = skip_first((*db)->zones);
 	dnslib_zone_t *zone = NULL;
 
diff --git a/src/knot/other/debug.h b/src/knot/other/debug.h
index 01feaff68fa099012030cc54a8c0371426d9eba4..121efb3ecd31a972f9134417926fb81f780b8398 100644
--- a/src/knot/other/debug.h
+++ b/src/knot/other/debug.h
@@ -20,7 +20,7 @@
 //#define SERVER_DEBUG
 //#define DT_DEBUG
 //#define NET_DEBUG
-#define ZONES_DEBUG
+//#define ZONES_DEBUG
 
 #ifdef SERVER_DEBUG
 #define debug_server(msg...) log_msg(LOG_SERVER, LOG_DEBUG, msg)
diff --git a/src/knot/server/name-server.c b/src/knot/server/name-server.c
index 0f2205d2466c943ef312a6e8cc4c6727ee3f8609..1133cfda156a2bbabf7c9d761207cd38b284db28 100644
--- a/src/knot/server/name-server.c
+++ b/src/knot/server/name-server.c
@@ -1763,18 +1763,27 @@ static int ns_response_to_wire(dnslib_response_t *resp, uint8_t *wire,
 /* Public functions                                                           */
 /*----------------------------------------------------------------------------*/
 
-ns_nameserver_t *ns_create(dnslib_zonedb_t *database)
+ns_nameserver_t *ns_create()
 {
 	ns_nameserver_t *ns = malloc(sizeof(ns_nameserver_t));
 	if (ns == NULL) {
 		ERR_ALLOC_FAILED;
 		return NULL;
 	}
-	ns->zone_db = database;
+
+	// Create zone database structure
+	debug_ns("Creating Zone Database structure...\n");
+	ns->zone_db = dnslib_zonedb_new();
+	if (ns->zone_db == NULL) {
+		ERR_ALLOC_FAILED;
+		free(ns);
+		return NULL;
+	}
 
 	// prepare empty response with SERVFAIL error
 	dnslib_response_t *err = dnslib_response_new_empty(NULL);
 	if (err == NULL) {
+		ERR_ALLOC_FAILED;
 		free(ns);
 		return NULL;
 	}
@@ -1913,11 +1922,16 @@ int ns_answer_request(ns_nameserver_t *nameserver, const uint8_t *query_wire,
 
 void ns_destroy(ns_nameserver_t **nameserver)
 {
-	// do nothing with the zone database!
+	synchronize_rcu();
+
 	free((*nameserver)->err_response);
 	if ((*nameserver)->opt_rr != NULL) {
 		dnslib_edns_free(&(*nameserver)->opt_rr);
 	}
+
+	// destroy the zone db
+	dnslib_zonedb_deep_free(&(*nameserver)->zone_db);
+
 	free(*nameserver);
 	*nameserver = NULL;
 }
@@ -1927,7 +1941,7 @@ void ns_destroy(ns_nameserver_t **nameserver)
 int ns_conf_hook(const struct conf_t *conf, void *data)
 {
 	ns_nameserver_t *ns = (ns_nameserver_t *)data;
-	debug_server("Event: reconfiguring name server.\n");
+	debug_ns("Event: reconfiguring name server.\n");
 
 	dnslib_zonedb_t *old_db = 0;
 
@@ -1938,6 +1952,8 @@ int ns_conf_hook(const struct conf_t *conf, void *data)
 	// Wait until all readers finish with reading the zones.
 	synchronize_rcu();
 
+	debug_ns("Nameserver's zone db: %p, old db: %p\n", ns->zone_db, old_db);
+
 	// Delete all deprecated zones and delete the old database.
 	dnslib_zonedb_deep_free(&old_db);
 
diff --git a/src/knot/server/name-server.h b/src/knot/server/name-server.h
index bd67adf0bfef1a70b7bc4309a87847331b37d668..8fc348126e355fe6aeabb75c74671b1d5890d41f 100644
--- a/src/knot/server/name-server.h
+++ b/src/knot/server/name-server.h
@@ -55,7 +55,7 @@ typedef struct ns_nameserver {
  *
  * \return Pointer to the name server structure.
  */
-ns_nameserver_t *ns_create(dnslib_zonedb_t *database);
+ns_nameserver_t *ns_create();
 
 /*!
  * \brief Creates a response for the given query using the data of the name
diff --git a/src/knot/server/server.c b/src/knot/server/server.c
index 595a5e1399f36b734fb4efcbe5e94e7af4e5b9a0..e98584f7112bec5025dd78177e757e76e7b50672 100644
--- a/src/knot/server/server.c
+++ b/src/knot/server/server.c
@@ -328,20 +328,10 @@ server_t *server_create()
 	server->ifaces = malloc(sizeof(list));
 	init_list(server->ifaces);
 
-	// Create zone database structure
-	debug_server("Creating Zone Database structure...\n");
-	server->zone_db = dnslib_zonedb_new();
-	if (server->zone_db == NULL) {
-		ERR_ALLOC_FAILED;
-		free(server);
-		return NULL;
-	}
-
 	// Create name server
 	debug_server("Creating Name Server structure...\n");
-	server->nameserver = ns_create(server->zone_db);
+	server->nameserver = ns_create();
 	if (server->nameserver == NULL) {
-		dnslib_zonedb_deep_free(&server->zone_db);
 		free(server);
 		return NULL;
 	}
@@ -634,7 +624,7 @@ void server_destroy(server_t **server)
 
 	stat_static_gath_free();
 	ns_destroy(&(*server)->nameserver);
-	dnslib_zonedb_deep_free(&(*server)->zone_db);
+
 	free(*server);
 
 	EVP_cleanup();
diff --git a/src/knot/server/zones.c b/src/knot/server/zones.c
index f7c55ae6f5c2f404556e89dd33b5a46853a200fb..3c25c66b1f21221e5eba40262d08a8c218de6f43 100644
--- a/src/knot/server/zones.c
+++ b/src/knot/server/zones.c
@@ -167,9 +167,15 @@ int zones_update_db_from_config(const conf_t *conf, ns_nameserver_t *ns,
 		return ret;
 	}
 
+	debug_zones("Old db in nameserver: %p, old db stored: %p, new db: %p\n",
+	            ns->zone_db, *db_old, db_new);
+
 	// Switch the databases.
 	(void)rcu_xchg_pointer(&ns->zone_db, db_new);
 
+	debug_zones("db in nameserver: %p, old db stored: %p, new db: %p\n",
+	            ns->zone_db, *db_old, db_new);
+
 	/*
 	 *  Remove all zones present in the new DB from the old DB.
 	 *  No new thread can access these zones in the old DB, as the