diff --git a/src/knot/conf/cf-lex.l b/src/knot/conf/cf-lex.l
index 0bb85d771da48f03c632cb6527a59dd058a26dd7..555c9aa1f4a5ac1305b554fffa26d0946a6623af 100644
--- a/src/knot/conf/cf-lex.l
+++ b/src/knot/conf/cf-lex.l
@@ -117,6 +117,7 @@ update-in       { lval.t = yytext; return UPDATE_IN; }
 notify-in       { lval.t = yytext; return NOTIFY_IN; }
 notify-out      { lval.t = yytext; return NOTIFY_OUT; }
 workers         { lval.t = yytext; return WORKERS; }
+background-workers { lval.t = yytext; return BACKGROUND_WORKERS; }
 user            { lval.t = yytext; return USER; }
 pidfile         { lval.t = yytext; return PIDFILE; }
 rundir          { lval.t = yytext; return RUNDIR; }
diff --git a/src/knot/conf/cf-parse.y b/src/knot/conf/cf-parse.y
index 58e3f0aeb38c7cb8d9fb6206d570389ce5a70ccf..dddaa6c63aeffdfca2eadaab71a25b26cd62039f 100644
--- a/src/knot/conf/cf-parse.y
+++ b/src/knot/conf/cf-parse.y
@@ -461,6 +461,7 @@ static void ident_auto(int tok, conf_t *conf, bool val)
 %token <tok> MAX_UDP_PAYLOAD
 %token <tok> TSIG_ALGO_NAME
 %token <tok> WORKERS
+%token <tok> BACKGROUND_WORKERS
 %token <tok> USER
 %token <tok> RUNDIR
 %token <tok> PIDFILE
@@ -590,6 +591,9 @@ system:
  | system WORKERS NUM ';' {
      SET_NUM(new_config->workers, $3.i, 1, 255, "workers");
  }
+ | system BACKGROUND_WORKERS NUM ';' {
+     SET_NUM(new_config->bg_workers, $3.i, 1, 255, "background-workers");
+ }
  | system USER TEXT ';' {
      new_config->uid = new_config->gid = -1; // Invalidate
      char* dpos = strchr($3.t, '.'); // Find uid.gid format
diff --git a/src/knot/conf/conf.h b/src/knot/conf/conf.h
index 217fa1a6a195acae60cca5d15474c0c99288d6cf..d7d3ed657b46cb0f4bcf1a90b9514f38b86622e9 100644
--- a/src/knot/conf/conf.h
+++ b/src/knot/conf/conf.h
@@ -215,6 +215,7 @@ typedef struct conf_t {
 	size_t nsid_len;/*!< Server's NSID length. */
 	size_t max_udp_payload; /*!< Maximal UDP payload size. */
 	int   workers;  /*!< Number of workers per interface. */
+	int   bg_workers; /*!< Number of background workers. */
 	int   uid;      /*!< Specified user id. */
 	int   gid;      /*!< Specified group id. */
 	int   max_conn_idle; /*!< TCP idle timeout. */
diff --git a/src/knot/main.c b/src/knot/main.c
index b18241b1d28436349c624c2f8480da72d4bc3035..ce9823805b09d4f3808c3f5794183cfd7c023d0c 100644
--- a/src/knot/main.c
+++ b/src/knot/main.c
@@ -280,7 +280,7 @@ int main(int argc, char **argv)
 
 	/* Initialize server. */
 	server_t server;
-	res = server_init(&server);
+	res = server_init(&server, config->bg_workers);
 	if (res != KNOT_EOK) {
 		log_server_fatal("Could not initialize server: %s\n",
 		                 knot_strerror(res));
diff --git a/src/knot/server/server.c b/src/knot/server/server.c
index 679a2b8129af8ee78419b1b95ad8c58310cfbf84..c7587c8a1d8a0da3f578fc2a790fb788c04321cb 100644
--- a/src/knot/server/server.c
+++ b/src/knot/server/server.c
@@ -261,7 +261,7 @@ static int reconfigure_sockets(const struct conf_t *conf, server_t *s)
 	return bound;
 }
 
-int server_init(server_t *server)
+int server_init(server_t *server, int bg_workers)
 {
 	/* Clear the structure. */
 	dbg_server("%s(%p)\n", __func__, server);
@@ -282,8 +282,12 @@ int server_init(server_t *server)
 	}
 
 	/* Create zone events threads. */
-#warning TODO: config option
-	server->workers = worker_pool_create(4); //! \todo config option
+	if (bg_workers < 1) {
+		bg_workers = dt_optimal_size();
+	}
+	assert(bg_workers > 0);
+
+	server->workers = worker_pool_create(bg_workers);
 	if (server->workers == NULL) {
 		dt_delete(&server->iosched);
 		evsched_deinit(&server->sched);
diff --git a/src/knot/server/server.h b/src/knot/server/server.h
index 696f8b388ae5f79cb8f9b421f41ca88bb8afa67e..248e103098e5c41dc7df6e81975366ac99e0d7b4 100644
--- a/src/knot/server/server.h
+++ b/src/knot/server/server.h
@@ -132,7 +132,7 @@ typedef struct server_t {
  * \retval KNOT_EOK on success.
  * \retval KNOT_EINVAL on invalid parameters.
  */
-int server_init(server_t *server);
+int server_init(server_t *server, int bg_workers);
 
 /*!
  * \brief Properly destroys the server structure.