diff --git a/src/knot/ctl/remote.c b/src/knot/ctl/remote.c
index 98feb3fb00c383c106a6c73f142e355b37ac07e4..4a6c815547f97668b0fbb2aedbe844b57bc5b421 100644
--- a/src/knot/ctl/remote.c
+++ b/src/knot/ctl/remote.c
@@ -50,7 +50,7 @@ typedef struct remote_cmdargs_t {
 typedef int (*remote_cmdf_t)(server_t*, remote_cmdargs_t*);
 
 /*! \brief Callback prototype for per-zone operations. */
-typedef int (remote_zonef_t)(server_t*, const zone_t *);
+typedef int (remote_zonef_t)(server_t*, zone_t *);
 
 /*! \brief Remote command table item. */
 typedef struct remote_cmd_t {
@@ -114,31 +114,29 @@ static int remote_rdata_apply(server_t *s, remote_cmdargs_t* a, remote_zonef_t *
 }
 
 /*! \brief Zone refresh callback. */
-static int remote_zone_refresh(server_t *server, const zone_t *zone)
+static int remote_zone_refresh(server_t *server, zone_t *zone)
 {
 	if (!server || !zone) {
 		return KNOT_EINVAL;
 	}
 
-#warning Implement me (schedule zone refresh)
-
+	zone_events_schedule(zone, ZONE_EVENT_REFRESH, ZONE_EVENT_NOW);
 	return KNOT_EOK;
 }
 
 /*! \brief Zone flush callback. */
-static int remote_zone_flush(server_t *server, const zone_t *zone)
+static int remote_zone_flush(server_t *server, zone_t *zone)
 {
 	if (!server || !zone) {
 		return KNOT_EINVAL;
 	}
 
-#warning Implement me (schedule zone file flush)
-
+	zone_events_schedule(zone, ZONE_EVENT_FLUSH, ZONE_EVENT_NOW);
 	return KNOT_EOK;
 }
 
 /*! \brief Sign zone callback. */
-static int remote_zone_sign(server_t *server, const zone_t *zone)
+static int remote_zone_sign(server_t *server, zone_t *zone)
 {
 	if (!server || !zone) {
 		return KNOT_EINVAL;
@@ -340,7 +338,8 @@ static int remote_c_refresh(server_t *s, remote_cmdargs_t* a)
 	dbg_server("remote: %s\n", __func__);
 	if (a->argc == 0) {
 		dbg_server_verb("remote: refreshing all zones\n");
-		knot_zonedb_foreach(s->zone_db, zones_schedule_refresh, ZONE_EVENT_NOW);
+		knot_zonedb_foreach(s->zone_db, zone_events_schedule,
+		                    ZONE_EVENT_REFRESH, ZONE_EVENT_NOW);
 		return KNOT_EOK;
 	}
 
diff --git a/src/knot/nameserver/notify.c b/src/knot/nameserver/notify.c
index 4614a51e71dacc9fa44b563f60e356352375e468..b38470438ba9534d7349c5d3e2b78982c43f345a 100644
--- a/src/knot/nameserver/notify.c
+++ b/src/knot/nameserver/notify.c
@@ -51,11 +51,12 @@ int internet_notify(knot_pkt_t *pkt, struct query_data *qdata)
 	}
 
 	/* RFC1996 require SOA question. */
+	zone_t *zone = (zone_t *)qdata->zone;
 	NS_NEED_QTYPE(qdata, KNOT_RRTYPE_SOA, KNOT_RCODE_FORMERR);
 
 	/* Check valid zone, transaction security. */
 	NS_NEED_ZONE(qdata, KNOT_RCODE_NOTAUTH);
-	NS_NEED_AUTH(qdata->zone->notify_in, qdata);
+	NS_NEED_AUTH(zone->notify_in, qdata);
 
 	/* Reserve space for TSIG. */
 	knot_pkt_reserve(pkt, tsig_wire_maxsize(qdata->sign.tsig_key));
@@ -73,19 +74,10 @@ int internet_notify(knot_pkt_t *pkt, struct query_data *qdata)
 		}
 	}
 
-	int next_state = NS_PROC_FAIL;
-
 	/* Incoming NOTIFY expires REFRESH timer and renews EXPIRE timer. */
-	int ret =  zones_schedule_refresh((zone_t *)qdata->zone, ZONE_EVENT_NOW);
+	zone_events_schedule(zone, ZONE_EVENT_REFRESH, ZONE_EVENT_NOW);
 
 	/* Format resulting log message. */
-	if (ret != KNOT_EOK) {
-		next_state = NS_PROC_NOOP; /* RFC1996: Ignore. */
-		NOTIFY_LOG(LOG_ERR, "%s", knot_strerror(ret));
-	} else {
-		next_state = NS_PROC_DONE;
-		NOTIFY_LOG(LOG_INFO, "received serial %u.", serial);
-	}
-
-	return next_state;
+	NOTIFY_LOG(LOG_INFO, "received serial %u.", serial);
+	return NS_PROC_DONE;
 }
diff --git a/src/knot/server/zone-load.c b/src/knot/server/zone-load.c
index 856f52afc41dbb41773815b91003b00182cb25bb..ef13fa962c18dde8e8a2e0d2e08f8481bec306ff 100644
--- a/src/knot/server/zone-load.c
+++ b/src/knot/server/zone-load.c
@@ -35,43 +35,6 @@
 
 #define XFRIN_BOOTSTRAP_DELAY 2000 /*!< AXFR bootstrap avg. delay */
 
-/*- zone file status --------------------------------------------------------*/
-
-/*!
- * \brief Zone file status.
- */
-typedef enum {
-	ZONE_STATUS_NOT_FOUND = 0,  //!< Zone file does not exist.
-	ZONE_STATUS_FOUND_NEW,      //!< Zone file exists, not loaded yet.
-	ZONE_STATUS_FOUND_CURRENT,  //!< Zone file exists, same as loaded.
-	ZONE_STATUS_FOUND_UPDATED,  //!< Zone file exists, newer than loaded.
-} zone_status_t;
-
-/*!
- * \brief Check zone file status.
- *
- * \param old_zone  Previous instance of the zone (can be NULL).
- * \param filename  File name of zone file.
- *
- * \return Zone status.
- */
-static zone_status_t zone_file_status(const zone_t *old_zone,
-                                      const char *filename)
-{
-	struct stat zf_stat = { 0 };
-	int result = stat(filename, &zf_stat);
-
-	if (result == -1) {
-		return ZONE_STATUS_NOT_FOUND;
-	} else if (old_zone == NULL) {
-		return ZONE_STATUS_FOUND_NEW;
-	} else if (old_zone->zonefile_mtime == zf_stat.st_mtime) {
-		return ZONE_STATUS_FOUND_CURRENT;
-	} else {
-		return ZONE_STATUS_FOUND_UPDATED;
-	}
-}
-
 /*- zone loading/updating ---------------------------------------------------*/
 
 /*!
@@ -157,164 +120,6 @@ zone_t *load_zone_file(conf_zone_t *conf)
 	return zone;
 }
 
-/*!
- * \brief Create a new zone structure according to documentation, but reuse
- *        existing zone content.
- */
-static zone_t *preserve_zone(conf_zone_t *conf, const zone_t *old_zone)
-{
-	assert(old_zone);
-
-	zone_t *new_zone = zone_new(conf);
-	if (!new_zone) {
-		log_zone_error("Preserving current zone '%s' failed: %s\n",
-		               conf->name, knot_strerror(KNOT_ENOMEM));
-		return NULL;
-	}
-
-	new_zone->contents = old_zone->contents;
-
-	return new_zone;
-}
-
-/*!
- * \brief Log message about loaded zone (name, status, serial).
- *
- * \param zone       Zone structure.
- * \param zone_name  Printable name of the zone.
- * \param status     Zone file status.
- */
-static void log_zone_load_info(const zone_t *zone, const char *zone_name,
-                               zone_status_t status)
-{
-	assert(zone);
-	assert(zone_name);
-
-	const char *action = NULL;
-
-	switch (status) {
-	case ZONE_STATUS_NOT_FOUND:     action = "bootstrapped";  break;
-	case ZONE_STATUS_FOUND_NEW:     action = "loaded";        break;
-	case ZONE_STATUS_FOUND_CURRENT: action = "is up-to-date"; break;
-	case ZONE_STATUS_FOUND_UPDATED: action = "reloaded";      break;
-	}
-	assert(action);
-
-	int64_t serial = 0;
-	if (zone->contents && zone->contents->apex) {
-		const knot_rdataset_t *soa = node_rdataset(zone->contents->apex,
-		                                           KNOT_RRTYPE_SOA);
-		serial = knot_soa_serial(soa);
-	}
-
-	log_zone_info("Zone '%s' %s (serial %" PRId64 ")\n", zone_name, action, serial);
-}
-
-/*!
- * \brief Load or reload the zone.
- *
- * \param old_zone  Already loaded zone (can be NULL).
- * \param conf      Zone configuration.
- * \param server    Name server.
- *
- * \return Error code, KNOT_EOK if successful.
- */
-static zone_t *create_zone(zone_t *old_zone, conf_zone_t *conf, server_t *server)
-{
-	assert(conf);
-
-	zone_status_t zstatus = zone_file_status(old_zone, conf->file);
-	zone_t *new_zone = NULL;
-
-	switch (zstatus) {
-	case ZONE_STATUS_NOT_FOUND:
-		new_zone = bootstrap_zone(conf);
-		break;
-	case ZONE_STATUS_FOUND_NEW:
-	case ZONE_STATUS_FOUND_UPDATED:
-		new_zone = load_zone_file(conf);
-		break;
-	case ZONE_STATUS_FOUND_CURRENT:
-		new_zone = preserve_zone(conf, old_zone);
-		break;
-	default:
-		assert(0);
-	}
-
-	if (!new_zone) {
-		log_server_error("Failed to load zone '%s'.\n", conf->name);
-		return NULL;
-	}
-
-	/* Initialize zone timers. */
-	zone_timers_create(new_zone, &server->sched);
-
-	log_zone_load_info(new_zone, conf->name, zstatus);
-
-	return new_zone;
-}
-
-/*!
- * \brief Load/reload the zone, apply journal, sign it and schedule XFR sync.
- *
- * \param[in]  old_zone  Old zone (if loaded).
- * \param[in]  conf      Zone configuration.
- * \param[in]  server    Name server structure.
- *
- * \return Updated zone on success, NULL otherwise.
- */
-static zone_t* update_zone(zone_t *old_zone, conf_zone_t *conf, server_t *server)
-{
-	assert(conf);
-
-	int result = KNOT_ERROR;
-
-	// Load zone.
-	zone_t *new_zone = create_zone(old_zone, conf, server);
-	if (!new_zone) {
-		return NULL;
-	}
-
-	bool new_content = (old_zone == NULL || old_zone->contents != new_zone->contents);
-
-	result = zones_journal_apply(new_zone);
-	if (result != KNOT_EOK && result != KNOT_ERANGE && result != KNOT_ENOENT) {
-		log_zone_error("Zone '%s' failed to apply changes from journal - %s\n",
-		               conf->name, knot_strerror(result));
-		goto fail;
-	}
-
-	result = zones_do_diff_and_sign(new_zone, old_zone, new_content);
-	if (result != KNOT_EOK) {
-		if (result == KNOT_ESPACE) {
-			log_zone_error("Zone '%s' journal size is too small to fit the changes.\n",
-			               conf->name);
-		} else {
-			log_zone_error("Zone '%s' failed to store changes in the journal - %s\n",
-			               conf->name, knot_strerror(result));
-		}
-		goto fail;
-	}
-
-fail:
-	assert(new_zone);
-
-	if (result == KNOT_EOK) {
-		return new_zone;
-	} else {
-		/* Preserved zone, don't free the shared contents. */
-		if (!new_content) {
-			new_zone->contents = NULL;
-		}
-
-		/* Disconnect config, caller is responsible for it. */
-		new_zone->conf = NULL;
-		zone_free(&new_zone);
-	}
-
-	return NULL;
-}
-
 /*!
  * \brief Check zone configuration constraints.
  */
@@ -345,237 +150,3 @@ static int update_zone_postcond(zone_t *new_zone, const conf_t *config)
 
 	return KNOT_EOK;
 }
-
-/*! \brief Context for threaded zone loader. */
-typedef struct {
-	const struct conf_t *config;
-	server_t        *server;
-	knot_zonedb_t   *db_old;
-	knot_zonedb_t   *db_new;
-	hattrie_iter_t  *z_iter;
-	pthread_mutex_t lock;
-} zone_loader_ctx_t;
-
-/*! Thread entrypoint for loading zones. */
-static int zone_loader_thread(dthread_t *thread)
-{
-	if (thread == NULL || thread->data == NULL) {
-		return KNOT_EINVAL;
-	}
-
-	zone_t *zone = NULL;
-	conf_zone_t *zone_config = NULL;
-	zone_loader_ctx_t *ctx = (zone_loader_ctx_t *)thread->data;
-	for(;;) {
-		/* Fetch zone configuration from the list. */
-		pthread_mutex_lock(&ctx->lock);
-		if (hattrie_iter_finished(ctx->z_iter)) {
-			pthread_mutex_unlock(&ctx->lock);
-			break;
-		}
-
-		/* Disconnect from the list and start processing. */
-		zone_config = (conf_zone_t *)*hattrie_iter_val(ctx->z_iter);
-		hattrie_iter_next(ctx->z_iter);
-		pthread_mutex_unlock(&ctx->lock);
-
-		/* Retrive old zone (if exists). */
-		knot_dname_t *apex = knot_dname_from_str(zone_config->name);
-		if (!apex) {
-			return KNOT_ENOMEM;
-		}
-		zone_t *old_zone = knot_zonedb_find(ctx->db_old, apex);
-		knot_dname_free(&apex, NULL);
-
-		/* Update the zone. */
-		zone = update_zone(old_zone, zone_config, ctx->server);
-		if (zone == NULL) {
-			conf_free_zone(zone_config);
-			continue;
-		}
-
-		/* Check updated zone post-conditions. */
-		int ret = update_zone_postcond(zone, ctx->config);
-
-		/* Insert into database if properly loaded. */
-		if (ret == KNOT_EOK) {
-			pthread_mutex_lock(&ctx->lock);
-			if (zone != NULL) {
-				ret = knot_zonedb_insert(ctx->db_new, zone);
-			}
-			pthread_mutex_unlock(&ctx->lock);
-		}
-
-		/* Check for any failure. */
-		if (ret != KNOT_EOK && zone) {
-			/* Preserved zone, don't free the shared contents. */
-			if (old_zone && old_zone->contents == zone->contents) {
-				zone->contents = NULL;
-			}
-
-			zone_free(&zone);
-		}
-	}
-
-	return KNOT_EOK;
-}
-
-static int zone_loader_destruct(dthread_t *thread)
-{
-	knot_crypto_cleanup_thread();
-	return KNOT_EOK;
-}
-
-/*!
- * \brief Fill the new database with zones.
- *
- * Zones that should be retained are just added from the old database to the
- * new. New zones are loaded.
- *
- * \param server Name server instance.
- * \param conf Server configuration.
- *
- * \return Number of inserted zones.
- */
-static knot_zonedb_t *load_zonedb(server_t *server, const conf_t *conf)
-{
-	/* Initialize threaded loader. */
-	zone_loader_ctx_t ctx = {0};
-	ctx.config = conf;
-	ctx.server = server;
-	ctx.db_old = server->zone_db;
-	ctx.db_new = knot_zonedb_new(hattrie_weight(conf->zones));
-	if (ctx.db_new == NULL) {
-		return NULL;
-	}
-
-	if (hattrie_weight(conf->zones) == 0) {
-		return ctx.db_new;
-	}
-
-	const bool sorted = false;
-	ctx.z_iter = hattrie_iter_begin(conf->zones, sorted);
-	if (ctx.z_iter == NULL) {
-		knot_zonedb_free(&ctx.db_new);
-		return NULL;
-	}
-
-	if (pthread_mutex_init(&ctx.lock, NULL) < 0) {
-		knot_zonedb_free(&ctx.db_new);
-		return NULL;
-	}
-
-	/* Initialize threads. */
-	size_t thread_count = MIN(hattrie_weight(conf->zones), dt_optimal_size());
-	dt_unit_t *unit = NULL;
-	unit = dt_create(thread_count, &zone_loader_thread,
-	                 &zone_loader_destruct, &ctx);
-	if (unit != NULL) {
-		/* Start loading. */
-		dt_start(unit);
-		dt_join(unit);
-		dt_delete(&unit);
-	} else {
-		knot_zonedb_free(&ctx.db_new);
-		ctx.db_new = NULL;
-	}
-
-	pthread_mutex_destroy(&ctx.lock);
-	hattrie_iter_free(ctx.z_iter);
-	return ctx.db_new;
-}
-
-/*!
- * \brief Remove old zones and zone database.
- *
- * \note Zone may be preserved in the new zone database, in this case
- *       new and old zone share the contents. Shared content is not freed.
- *
- * \param db_new New zone database.
- * \param db_old Old zone database.
-  */
-static int remove_old_zonedb(const knot_zonedb_t *db_new, knot_zonedb_t *db_old)
-{
-	if (db_old == NULL) {
-		return KNOT_EOK; /* Nothing to free. */
-	}
-
-	knot_zonedb_iter_t it;
-	knot_zonedb_iter_begin(db_new, &it);
-
-	while(!knot_zonedb_iter_finished(&it)) {
-		zone_t *new_zone = knot_zonedb_iter_val(&it);
-		zone_t *old_zone = knot_zonedb_find(db_old, new_zone->name);
-
-		/* If the zone exists in both new and old database and the contents
-		 * didn't change. We must invalidate the pointer in the old zone
-		 * to preserve the contents.
-		 */
-		if (old_zone && old_zone->contents == new_zone->contents) {
-			old_zone->contents = NULL;
-		}
-
-		knot_zonedb_iter_next(&it);
-	}
-
-	/* Delete all deprecated zones and delete the old database. */
-	knot_zonedb_deep_free(&db_old);
-
-	return KNOT_EOK;
-}
-
-/*- public API functions ----------------------------------------------------*/
-
-/*!
- * \brief Update zone database according to configuration.
- */
-int load_zones_from_config(const conf_t *conf, struct server_t *server)
-{
-	/* Check parameters */
-	if (conf == NULL || server == NULL) {
-		return KNOT_EINVAL;
-	}
-
-	/* Freeze zone timers. */
-	if (server->zone_db) {
-		knot_zonedb_foreach(server->zone_db, zone_timers_freeze);
-	}
-
-	/* Insert all required zones to the new zone DB. */
-	/*! \warning RCU must not be locked as some contents switching will
-	             be required. */
-	knot_zonedb_t *db_new = load_zonedb(server, conf);
-	if (db_new == NULL) {
-		log_server_warning("Failed to load zones.\n");
-		return KNOT_ENOMEM;
-	} else {
-		size_t loaded = knot_zonedb_size(db_new);
-		log_server_info("Loaded %zu out of %zu zones.\n",
-		                loaded, hattrie_weight(conf->zones));
-		if (loaded != hattrie_weight(conf->zones)) {
-			log_server_warning("Not all the zones were loaded.\n");
-		}
-	}
-
-	/* Rebuild zone database search stack. */
-	knot_zonedb_build_index(db_new);
-
-	/* Switch the databases. */
-	knot_zonedb_t *db_old = rcu_xchg_pointer(&server->zone_db, db_new);
-
-	/* Wait for readers to finish reading old zone database. */
-	synchronize_rcu();
-
-	/* Thaw zone events now that the database is published. */
-	if (server->zone_db) {
-		knot_zonedb_foreach(server->zone_db, zone_timers_thaw);
-		knot_zonedb_foreach(server->zone_db, zones_schedule_notify, server);
-	}
-
-	/*
-	 * 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
-	 * databases are already switched.
-	 */
-	return remove_old_zonedb(db_new, db_old);
-}
diff --git a/src/knot/updates/xfr-in.c b/src/knot/updates/xfr-in.c
index 2d48fd0ce0f530632929c5007390eeed4e2b4e21..f841e2aba3ecd30af2ebc37dc2bbff34da59dffc 100644
--- a/src/knot/updates/xfr-in.c
+++ b/src/knot/updates/xfr-in.c
@@ -109,41 +109,6 @@ int xfrin_transfer_needed(const zone_contents_t *zone,
 
 /*----------------------------------------------------------------------------*/
 
-int xfrin_create_soa_query(const zone_t *zone, knot_pkt_t *pkt)
-{
-	return knot_pkt_put_question(pkt, zone->name, KNOT_CLASS_IN, KNOT_RRTYPE_SOA);
-}
-
-/*----------------------------------------------------------------------------*/
-
-int xfrin_create_axfr_query(const zone_t *zone, knot_pkt_t *pkt)
-{
-	return knot_pkt_put_question(pkt, zone->name, KNOT_CLASS_IN, KNOT_RRTYPE_AXFR);
-}
-
-/*----------------------------------------------------------------------------*/
-
-int xfrin_create_ixfr_query(const zone_t *zone, knot_pkt_t *pkt)
-{
-	if (zone->contents == NULL) {
-		return KNOT_EINVAL;
-	}
-
-	int ret = knot_pkt_put_question(pkt, zone->name, KNOT_CLASS_IN, KNOT_RRTYPE_IXFR);
-	if (ret != KNOT_EOK) {
-		return ret;
-	}
-
-	/* Add SOA RR to authority section for IXFR. */
-	zone_node_t *apex = zone->contents->apex;
-	knot_rrset_t soa = node_rrset(apex, KNOT_RRTYPE_SOA);
-	knot_pkt_begin(pkt, KNOT_AUTHORITY);
-	ret = knot_pkt_put(pkt, COMPR_HINT_QNAME, &soa, 0);
-	return ret;
-}
-
-/*----------------------------------------------------------------------------*/
-
 static int xfrin_check_tsig(knot_pkt_t *packet, knot_ns_xfr_t *xfr,
                             int tsig_req)
 {
diff --git a/src/knot/updates/xfr-in.h b/src/knot/updates/xfr-in.h
index 6dbbe20cd4ab2ca6863c8835c89dfe76ae65c0a2..5d3d1a2923c4c2e066b6462d622b42e191f23623 100644
--- a/src/knot/updates/xfr-in.h
+++ b/src/knot/updates/xfr-in.h
@@ -62,46 +62,6 @@ typedef enum xfrin_transfer_result {
 int xfrin_transfer_needed(const zone_contents_t *zone,
                           knot_pkt_t *soa_response);
 
-/*!
- * \brief Creates normal query for the given zone name and the SOA type.
- *
- * \param zone Zone for which a query should be created.
- * \param pkt Packet to be written.
- *
- * \retval KNOT_EOK
- * \retval KNOT_ESPACE
- * \retval KNOT_ERROR
- */
-int xfrin_create_soa_query(const zone_t *zone, knot_pkt_t *pkt);
-
-/*!
- * \brief Creates normal query for the given zone name and the AXFR type.
- *
- * \param zone Zone for which a query should be created.
- * \param pkt Packet to be written.
- *
- * \todo Parameter use_tsig probably not needed.
- *
- * \retval KNOT_EOK
- * \retval KNOT_ESPACE
- * \retval KNOT_ERROR
- */
-int xfrin_create_axfr_query(const zone_t *zone, knot_pkt_t *pkt);
-
-/*!
- * \brief Creates normal query for the given zone name and the IXFR type.
- *
- * \param zone Zone for which a query should be created.
- * \param pkt Packet to be written.
- *
- * \todo Parameter use_tsig probably not needed.
- *
- * \retval KNOT_EOK
- * \retval KNOT_ESPACE
- * \retval KNOT_ERROR
- */
-int xfrin_create_ixfr_query(const zone_t *zone, knot_pkt_t *pkt);
-
 /*!
  * \brief Processes one incoming packet of AXFR transfer by updating the given
  *        zone.
diff --git a/src/knot/zone/events.c b/src/knot/zone/events.c
index 851d0465c256a0e90217b8f523e3cb78f08e2ce7..464610a31d313ccd8bc389a8ba479e00592a591f 100644
--- a/src/knot/zone/events.c
+++ b/src/knot/zone/events.c
@@ -694,99 +694,6 @@ void zone_events_start(zone_t *zone)
 }
 
 /* ------------ Legacy API to be converted (not functional now) ------------- */
-#warning TODO: vvv legacy API to be converted vvv
-
-
-int zones_schedule_refresh(zone_t *zone, int64_t timeout)
-{
-	if (!zone) {
-		return KNOT_EINVAL;
-	}
-#warning TODO: reimplement schedule_refresh
-#if 0
-	/* Cancel REFRESH/EXPIRE timer. */
-//	evsched_cancel(zone->xfr_in.expire);
-//	evsched_cancel(zone->xfr_in.timer);
-
-	/* Check XFR/IN master server. */
-	pthread_mutex_lock(&zone->lock);
-	rcu_read_lock();
-	if (zone_master(zone) != NULL) {
-
-		knot_rdataset_t *soa = zone_contents_soa(zone->contents);
-
-		/* Schedule EXPIRE timer. */
-		if (zone->contents != NULL) {
-			int64_t expire_tmr = knot_soa_expire(soa);
-			// Allow for timeouts.  Otherwise zones with very short
-			// expiry may expire before the timeout is reached.
-			expire_tmr += 2 * (conf()->max_conn_idle * 1000);
-//			evsched_schedule(zone->xfr_in.expire, expire_tmr);
-
-		}
-
-		/* Schedule REFRESH timer. */
-		if (timeout < 0) {
-			if (zone->contents) {
-				timeout = knot_soa_refresh(soa);
-			} else {
-				timeout = zone->xfr_in.bootstrap_retry;
-			}
-		}
-//		evsched_schedule(zone->xfr_in.timer, timeout);
-
-	}
-	rcu_read_unlock();
-	pthread_mutex_unlock(&zone->lock);
-#endif
-
-	return KNOT_EOK;
-}
-
-int zones_schedule_notify(zone_t *zone, server_t *server)
-{
-	if (!zone) {
-		return KNOT_EINVAL;
-	}
-
-#warning TODO: reimplement schedule_notify
-#if 0
-	/* Do not issue NOTIFY queries if stub. */
-	if (!zone->contents) {
-		return KNOT_EOK;
-	}
-
-	/* Schedule NOTIFY to slaves. */
-	conf_zone_t *cfg = zone->conf;
-	conf_remote_t *r = 0;
-	WALK_LIST(r, cfg->acl.notify_out) {
-
-		/* Fetch remote. */
-		conf_iface_t *cfg_if = r->remote;
-
-		/* Create request. */
-		knot_ns_xfr_t *rq = xfr_task_create(zone, XFR_TYPE_NOTIFY, XFR_FLAG_UDP);
-		if (!rq) {
-			log_zone_error("Failed to create NOTIFY for '%s', "
-			               "not enough memory.\n", cfg->name);
-			continue;
-		}
-
-		xfr_task_setaddr(rq, &cfg_if->addr, &cfg_if->via);
-		rq->tsig_key = cfg_if->key;
-
-		rq->data = (void *)((long)cfg->notify_retries);
-#warning "XFR enqueue."
-//		if (xfr_enqueue(server->xfr, rq) != KNOT_EOK) {
-//			log_zone_error("Failed to enqueue NOTIFY for '%s'.\n",
-//			               cfg->name);
-//			continue;
-//		}
-	}
-#endif
-
-	return KNOT_EOK;
-}
 
 int zones_schedule_dnssec(zone_t *zone, time_t unixtime)
 {
diff --git a/src/knot/zone/events.h b/src/knot/zone/events.h
index 56469de84da9270fe6b76904fe7b3b0d20c8d15f..06ac57f10bb17127dba9584f5946b963e34970ec 100644
--- a/src/knot/zone/events.h
+++ b/src/knot/zone/events.h
@@ -106,31 +106,6 @@ void zone_events_start(struct zone_t *zone);
 
 /* ------------ Legacy API to be converted (not functional now) ------------- */
 
-#define REFRESH_DEFAULT -1
-
-/*!
- * \brief Update zone timers.
- *
- * REFRESH/RETRY/EXPIRE timers are updated according to SOA.
- *
- * \param zone Related zone.
- * \param time Specific timeout or REFRESH_DEFAULT for default.
- *
- * \retval KNOT_EOK
- * \retval KNOT_EINVAL
- * \retval KNOT_ERROR
- */
-int zones_schedule_refresh(struct zone_t *zone, int64_t timeout);
-
-/*!
- * \brief Schedule NOTIFY after zone update.
- * \param zone Related zone.
- *
- * \retval KNOT_EOK
- * \retval KNOT_ERROR
- */
-int zones_schedule_notify(struct zone_t *zone, struct server_t *server);
-
 /*!
  * \brief Schedule DNSSEC event.
  * \param zone Related zone.
diff --git a/src/knot/zone/zonedb-load.c b/src/knot/zone/zonedb-load.c
index 2a8391d772f763ab74f69985ff6a0e4307f5969d..77ce66101c266a8ba641d3e20ff6daad49ddeaed 100644
--- a/src/knot/zone/zonedb-load.c
+++ b/src/knot/zone/zonedb-load.c
@@ -27,10 +27,6 @@
 #include "knot/server/server.h"
 #include "libknot/dname.h"
 
-/* Constants */
-
-#define XFRIN_BOOTSTRAP_DELAY 2000 /*!< AXFR bootstrap avg. delay */
-
 /*- zone file status --------------------------------------------------------*/
 
 /*!