diff --git a/daemon/bindings.c b/daemon/bindings.c
index 43f7468a79052848e8e66cfe376202f41352edea..b009814f84bf9b91c9344da498309d410643cbba 100644
--- a/daemon/bindings.c
+++ b/daemon/bindings.c
@@ -267,23 +267,45 @@ int lib_net(lua_State *L)
 	return 1;
 }
 
+/** Return number of cached records. */
+static int cache_count(lua_State *L)
+{
+	struct engine *engine = engine_luaget(L);
+	const namedb_api_t *storage = kr_cache_storage();
+
+	/* Fetch item count */
+	namedb_txn_t txn;
+	int ret = kr_cache_txn_begin(engine->resolver.cache, &txn, NAMEDB_RDONLY);
+	if (ret != 0) {
+		lua_pushstring(L, kr_strerror(ret));
+		lua_error(L);
+	}
+
+	lua_pushinteger(L, storage->count(&txn));
+	kr_cache_txn_abort(&txn);
+	return 1;
+}
+
 /** Open cache */
 static int cache_open(lua_State *L)
 {
 	/* Check parameters */
 	int n = lua_gettop(L);
-	if (n < 2) {
-		lua_pushstring(L, "expected (string path, int size)");
+	if (n < 1) {
+		lua_pushstring(L, "expected (number max_size)");
 		lua_error(L);
 	}
 
-	/* Open resolution context cache */
+	/* Close if already open */
 	struct engine *engine = engine_luaget(L);
-	engine->resolver.cache = kr_cache_open(lua_tostring(L, 1), engine->pool, lua_tointeger(L, 2));
+	if (engine->resolver.cache != NULL) {
+		kr_cache_close(engine->resolver.cache);
+	}
+
+	/* Open resolution context cache */
+	engine->resolver.cache = kr_cache_open(".", engine->pool, lua_tointeger(L, 1));
 	if (engine->resolver.cache == NULL) {
-		lua_pushstring(L, "invalid cache directory: ");
-		lua_pushstring(L, lua_tostring(L, 1));
-		lua_concat(L, 2);
+		lua_pushstring(L, "can't open cache in rundir");
 		lua_error(L);
 	}
 
@@ -295,8 +317,9 @@ static int cache_close(lua_State *L)
 {
 	struct engine *engine = engine_luaget(L);
 	if (engine->resolver.cache != NULL) {
-		kr_cache_close(engine->resolver.cache);
+		struct kr_cache *cache = engine->resolver.cache;
 		engine->resolver.cache = NULL;
+		kr_cache_close(cache);
 	}
 
 	lua_pushboolean(L, 1);
@@ -306,6 +329,7 @@ static int cache_close(lua_State *L)
 int lib_cache(lua_State *L)
 {
 	static const luaL_Reg lib[] = {
+		{ "count",  cache_count },
 		{ "open",   cache_open },
 		{ "close",  cache_close },
 		{ NULL, NULL }
diff --git a/modules/cachectl/README.rst b/modules/cachectl/README.rst
index ebf86466f7f5b53255143250e7e72fb7f845659c..448049cbad8016299220e751bf5f148b7dacb801 100644
--- a/modules/cachectl/README.rst
+++ b/modules/cachectl/README.rst
@@ -1,16 +1,11 @@
 Cache control
-~~~~~~~~~~~~~
+-------------
 
 Module providing an interface to cache database, for inspection, manipulation and purging.
 
 Properties
-..........
+^^^^^^^^^^
 
-``get_size``
-	Return number of cached records.
-
-	:Input:  N/A
-	:Output: ``{ size: int }``
 ``prune``
 	Prune expired/invalid records.
 
diff --git a/modules/cachectl/cachectl.c b/modules/cachectl/cachectl.c
index 59290311e89363a1b55c2fac65ee51649ebc40ea..24a78e9f4894a9d8e6d26a28213bf7b7cd20e869 100644
--- a/modules/cachectl/cachectl.c
+++ b/modules/cachectl/cachectl.c
@@ -35,32 +35,6 @@
  * Properties.
  */
 
-/**
- * Return number of cached records.
- *
- * Input:  N/A
- * Output: { size: int }
- *
- */
-static char* get_size(void *env, struct kr_module *module, const char *args)
-{
-	char *result = NULL;
-	struct engine *engine = env;
-	const namedb_api_t *storage = kr_cache_storage();
-
-	/* Fetch item count */
-	namedb_txn_t txn;
-	int ret = kr_cache_txn_begin(engine->resolver.cache, &txn, NAMEDB_RDONLY);
-	if (ret == 0) {
-		asprintf(&result, "{ \"size\": %d }", storage->count(&txn));
-		kr_cache_txn_abort(&txn);
-	} else {
-		asprintf(&result, "{ \"error\": \"%s\" }", knot_strerror(ret));
-	}
-
-	return result;
-}
-
 /** Return boolean true if a record in the RR set is expired. */
 static int is_expired(struct kr_cache_rrset *rr, uint32_t drift)
 {
@@ -165,7 +139,6 @@ static char* clear(void *env, struct kr_module *module, const char *args)
 struct kr_prop *cachectl_props(void)
 {
 	static struct kr_prop prop_list[] = {
-	    { &get_size, "size",  "Return number of cached records.", },
 	    { &prune,    "prune", "Prune expired/invalid records.", },
 	    { &clear,    "clear", "Clear all cache records.", },
 	    { NULL, NULL, NULL }