diff --git a/src/box/iproto.cc b/src/box/iproto.cc
index 78453f756c75f376ac93ca53ad7d8f42ca6fd96d..f5bd810b08b28e07c0318e086456aacc3305962d 100644
--- a/src/box/iproto.cc
+++ b/src/box/iproto.cc
@@ -2824,13 +2824,8 @@ struct iproto_cfg_msg: public cbus_call_msg
 	/** Operation to execute in iproto thread. */
 	enum iproto_cfg_op op;
 	union {
-		/** statistic stucture */
-		struct {
-			size_t mem_used;
-			size_t connections;
-			size_t requests;
-			size_t streams;
-		};
+		/** Pointer to the statistic stucture. */
+		struct iproto_stats *stats;
 		/** Pointer to evio_service, used for bind */
 		struct evio_service *binary;
 
@@ -2862,15 +2857,16 @@ static void
 iproto_fill_stat(struct iproto_thread *iproto_thread,
 		 struct iproto_cfg_msg *cfg_msg)
 {
-	cfg_msg->mem_used =
+	assert(cfg_msg->stats != NULL);
+	cfg_msg->stats->mem_used =
 		slab_cache_used(&iproto_thread->net_cord.slabc) +
 		slab_cache_used(&iproto_thread->net_slabc);
-	cfg_msg->connections =
+	cfg_msg->stats->connections =
 		mempool_count(&iproto_thread->iproto_connection_pool);
-	cfg_msg->requests =
-		mempool_count(&iproto_thread->iproto_msg_pool);
-	cfg_msg->streams =
+	cfg_msg->stats->streams =
 		mempool_count(&iproto_thread->iproto_stream_pool);
+	cfg_msg->stats->requests =
+		mempool_count(&iproto_thread->iproto_msg_pool);
 }
 
 static int
@@ -2972,86 +2968,36 @@ iproto_listen(const char *uri)
 	return 0;
 }
 
-size_t
-iproto_mem_used(void)
-{
-	struct iproto_cfg_msg cfg_msg;
-	size_t mem = 0;
-	iproto_cfg_msg_create(&cfg_msg, IPROTO_CFG_STAT);
-	for (int i = 0; i < iproto_threads_count; i++) {
-		iproto_do_cfg(&iproto_threads[i], &cfg_msg);
-		mem += cfg_msg.mem_used;
-	}
-	return mem;
-}
-
-size_t
-iproto_connection_count(void)
-{
-	struct iproto_cfg_msg cfg_msg;
-	size_t count = 0;
-	iproto_cfg_msg_create(&cfg_msg, IPROTO_CFG_STAT);
-	for (int i = 0; i < iproto_threads_count; i++) {
-		iproto_do_cfg(&iproto_threads[i], &cfg_msg);
-		count += cfg_msg.connections;
-	}
-	return count;
-}
-
-size_t
-iproto_thread_connection_count(int thread_id)
-{
-	struct iproto_cfg_msg cfg_msg;
-	iproto_cfg_msg_create(&cfg_msg, IPROTO_CFG_STAT);
-	assert(thread_id >= 0 && thread_id < iproto_threads_count);
-	iproto_do_cfg(&iproto_threads[thread_id], &cfg_msg);
-	return cfg_msg.connections;
-}
-
-size_t
-iproto_stream_count(void)
-{
-	struct iproto_cfg_msg cfg_msg;
-	size_t count = 0;
-	iproto_cfg_msg_create(&cfg_msg, IPROTO_CFG_STAT);
-	for (int i = 0; i < iproto_threads_count; i++) {
-		iproto_do_cfg(&iproto_threads[i], &cfg_msg);
-		count += cfg_msg.streams;
-	}
-	return count;
-}
-
-size_t
-iproto_thread_stream_count(int thread_id)
+static void
+iproto_stats_add(struct iproto_stats *total_stats,
+		 struct iproto_stats *thread_stats)
 {
-	struct iproto_cfg_msg cfg_msg;
-	iproto_cfg_msg_create(&cfg_msg, IPROTO_CFG_STAT);
-	assert(thread_id >= 0 && thread_id < iproto_threads_count);
-	iproto_do_cfg(&iproto_threads[thread_id], &cfg_msg);
-	return cfg_msg.streams;
+	total_stats->mem_used += thread_stats->mem_used;
+	total_stats->connections += thread_stats->connections;
+	total_stats->streams += thread_stats->streams;
+	total_stats->requests += thread_stats->requests;
 }
 
-size_t
-iproto_request_count(void)
+void
+iproto_stats_get(struct iproto_stats *stats)
 {
-	struct iproto_cfg_msg cfg_msg;
-	size_t count = 0;
-	iproto_cfg_msg_create(&cfg_msg, IPROTO_CFG_STAT);
+	struct iproto_stats thread_stats;
+	memset(stats, 0, sizeof(iproto_stats));
 	for (int i = 0; i < iproto_threads_count; i++) {
-		iproto_do_cfg(&iproto_threads[i], &cfg_msg);
-		count += cfg_msg.requests;
+		iproto_thread_stats_get(&thread_stats, i);
+		iproto_stats_add(stats, &thread_stats);
 	}
-	return count;
 }
 
-size_t
-iproto_thread_request_count(int thread_id)
+void
+iproto_thread_stats_get(struct iproto_stats *stats, int thread_id)
 {
+	memset(stats, 0, sizeof(iproto_stats));
 	struct iproto_cfg_msg cfg_msg;
 	iproto_cfg_msg_create(&cfg_msg, IPROTO_CFG_STAT);
 	assert(thread_id >= 0 && thread_id < iproto_threads_count);
+	cfg_msg.stats = stats;
 	iproto_do_cfg(&iproto_threads[thread_id], &cfg_msg);
-	return cfg_msg.requests;
 }
 
 void
diff --git a/src/box/iproto.h b/src/box/iproto.h
index 6e24dcd9a1e0f2392b0d53db28f7cc857b8ae90b..a35a552b1a8db0571c261c9963fb740986c8dd78 100644
--- a/src/box/iproto.h
+++ b/src/box/iproto.h
@@ -56,53 +56,32 @@ enum {
 	IPROTO_THREADS_MAX = 1000,
 };
 
+struct iproto_stats {
+	/** Size of memory used for storing network buffers. */
+	size_t mem_used;
+	/** Number of active iproto connections. */
+	size_t connections;
+	/** Number of active iproto streams. */
+	size_t streams;
+	/** Number of iproto requests in flight. */
+	size_t requests;
+};
+
 extern unsigned iproto_readahead;
 extern int iproto_threads_count;
 
 /**
- * Return size of memory used for storing network buffers.
- */
-size_t
-iproto_mem_used(void);
-
-/**
- * Return the number of active iproto connections.
+ * Return total iproto statistic.
  */
-size_t
-iproto_connection_count(void);
-
-/**
- * Return the number of active iproto connections
- * for the thread with the given id.
- */
-size_t
-iproto_thread_connection_count(int thread_id);
-
-/**
- * Return the number of active iproto streams.
- */
-size_t
-iproto_stream_count(void);
-
-/**
- * Return the number of active iproto streams
- * for the thread with the given id.
- */
-size_t
-iproto_thread_stream_count(int thread_id);
-
-/**
- * Return the number of iproto requests in flight.
- */
-size_t
-iproto_request_count(void);
+void
+iproto_stats_get(struct iproto_stats *stats);
 
 /**
- * Return the number of iproto requests in flight
- * for the thread with the given id.
+ * Return total iproto statistic for
+ * the thread with the given id.
  */
-size_t
-iproto_thread_request_count(int thread_id);
+void
+iproto_thread_stats_get(struct iproto_stats *stats, int thread_id);
 
 /**
  * Reset network statistics.
diff --git a/src/box/lua/info.c b/src/box/lua/info.c
index 040af306a488f7de1025c8484e29be237f2edd02..6e13041b2217a4c1ab34bff67b3f501c4f6b4d36 100644
--- a/src/box/lua/info.c
+++ b/src/box/lua/info.c
@@ -405,8 +405,10 @@ lbox_info_memory_call(struct lua_State *L)
 	luaL_pushuint64(L, stat.tx);
 	lua_settable(L, -3);
 
+	struct iproto_stats stats;
+	iproto_stats_get(&stats);
 	lua_pushstring(L, "net");
-	luaL_pushuint64(L, iproto_mem_used());
+	luaL_pushuint64(L, stats.mem_used);
 	lua_settable(L, -3);
 
 	lua_pushstring(L, "lua");
diff --git a/src/box/lua/stat.c b/src/box/lua/stat.c
index 195c11931f2d6dc9f1452129797bf69643ea164b..946d067acf07f83afe192f7db3c35e150996738e 100644
--- a/src/box/lua/stat.c
+++ b/src/box/lua/stat.c
@@ -67,6 +67,14 @@ inject_current_stat(struct lua_State *L, const char *name, size_t val)
 	lua_pop(L, 1);
 }
 
+static void
+inject_iproto_stats(struct lua_State *L, struct iproto_stats *stats)
+{
+	inject_current_stat(L, "CONNECTIONS", stats->connections);
+	inject_current_stat(L, "REQUESTS", stats->requests);
+	inject_current_stat(L, "STREAMS", stats->streams);
+}
+
 static void
 fill_stat_item(struct lua_State *L, int rps, int64_t total)
 {
@@ -165,17 +173,19 @@ lbox_stat_net_index(struct lua_State *L)
 	if (iproto_rmean_foreach(seek_stat_item, L) == 0)
 		return 0;
 
+	struct iproto_stats stats;
+	iproto_stats_get(&stats);
 	if (strcmp(key, "CONNECTIONS") == 0) {
 		lua_pushstring(L, "current");
-		lua_pushnumber(L, iproto_connection_count());
+		lua_pushnumber(L, stats.connections);
 		lua_rawset(L, -3);
 	} else if (strcmp(key, "REQUESTS") == 0) {
 		lua_pushstring(L, "current");
-		lua_pushnumber(L, iproto_request_count());
+		lua_pushnumber(L, stats.requests);
 		lua_rawset(L, -3);
 	} else if (strcmp(key, "STREAMS") == 0) {
 		lua_pushstring(L, "current");
-		lua_pushnumber(L, iproto_stream_count());
+		lua_pushnumber(L, stats.streams);
 		lua_rawset(L, -3);
 	}
 	return 1;
@@ -202,45 +212,37 @@ lbox_stat_net_call(struct lua_State *L)
 {
 	lua_newtable(L);
 	iproto_rmean_foreach(set_stat_item, L);
-	inject_current_stat(L, "CONNECTIONS", iproto_connection_count());
-	inject_current_stat(L, "REQUESTS", iproto_request_count());
-	inject_current_stat(L, "STREAMS", iproto_stream_count());
+	struct iproto_stats stats;
+	iproto_stats_get(&stats);
+	inject_iproto_stats(L, &stats);
 	return 1;
 }
 
 static int
 lbox_stat_net_thread_index(struct lua_State *L)
 {
-	size_t value;
 	const int thread_id = luaL_checkinteger(L, -1) - 1;
 	if (thread_id < 0 || thread_id > iproto_threads_count)
 		return 0;
 
 	lua_newtable(L);
 	iproto_thread_rmean_foreach(thread_id, set_stat_item, L);
-	value = iproto_thread_connection_count(thread_id);
-	inject_current_stat(L, "CONNECTIONS", value);
-	value = iproto_thread_request_count(thread_id);
-	inject_current_stat(L, "REQUESTS", value);
-	value = iproto_thread_stream_count(thread_id);
-	inject_current_stat(L, "STREAMS", value);
+	struct iproto_stats stats;
+	iproto_thread_stats_get(&stats, thread_id);
+	inject_iproto_stats(L, &stats);
 	return 1;
 }
 
 static int
 lbox_stat_net_thread_call(struct lua_State *L)
 {
-	size_t value;
+	struct iproto_stats stats;
 	lua_newtable(L);
 	for (int thread_id = 0; thread_id < iproto_threads_count; thread_id++) {
 		lua_newtable(L);
 		iproto_thread_rmean_foreach(thread_id, set_stat_item, L);
-		value = iproto_thread_connection_count(thread_id);
-		inject_current_stat(L, "CONNECTIONS", value);
-		value = iproto_thread_request_count(thread_id);
-		inject_current_stat(L, "REQUESTS", value);
-		value = iproto_thread_stream_count(thread_id);
-		inject_current_stat(L, "STREAMS", value);
+		iproto_thread_stats_get(&stats, thread_id);
+		inject_iproto_stats(L, &stats);
 		lua_rawseti(L, -2, thread_id + 1);
 	}
 	return 1;