diff --git a/include/mhash.h b/include/mhash.h
index e6bfc1943896cc35fffa1589125b72cda194803f..1d8c080811ce0bd637498a578315e2f7b813f224 100644
--- a/include/mhash.h
+++ b/include/mhash.h
@@ -151,6 +151,7 @@ void _mh(reserve)(struct _mh(t) *h, mh_int_t size,
 		  mh_arg_t arg);
 void __attribute__((noinline)) _mh(del_resize)(struct _mh(t) *h, mh_int_t x,
 					       mh_arg_t arg);
+size_t _mh(memsize)(struct _mh(t) *h);
 void _mh(dump)(struct _mh(t) *h);
 
 #define put_slot(h, node, arg) \
@@ -377,7 +378,7 @@ _mh(new)()
 	h->prime = 0;
 	h->n_buckets = __ac_prime_list[h->prime];
 	h->p = (mh_node_t *) calloc(h->n_buckets, sizeof(mh_node_t));
-	h->b = (mh_int_t *) calloc(h->n_buckets / 16 + 1, sizeof(unsigned));
+	h->b = (mh_int_t *) calloc(h->n_buckets / 16 + 1, sizeof(mh_int_t));
 	h->upper_bound = h->n_buckets * MH_DENSITY;
 	return h;
 }
@@ -401,6 +402,22 @@ _mh(delete)(struct _mh(t) *h)
 	free(h);
 }
 
+/** Calculate hash size. */
+size_t
+_mh(memsize)(struct _mh(t) *h)
+{
+    size_t sz = 2 * sizeof(struct _mh(t));
+
+    sz += h->n_buckets * sizeof(mh_node_t);
+    sz += (h->n_buckets / 16 + 1) * sizeof(mh_int_t);
+    if (h->resize_position) {
+	    h = h->shadow;
+	    sz += h->n_buckets * sizeof(mh_node_t);
+	    sz += (h->n_buckets / 16 + 1) * sizeof(mh_int_t);
+    }
+    return sz;
+}
+
 void
 _mh(resize)(struct _mh(t) *h,
 	    mh_arg_t arg)
@@ -467,7 +484,7 @@ _mh(start_resize)(struct _mh(t) *h, mh_int_t buckets, mh_int_t batch,
 	s->p = (mh_node_t *) malloc(s->n_buckets * sizeof(mh_node_t));
 	if (s->p == NULL)
 		return -1;
-	s->b = (mh_int_t *) calloc(s->n_buckets / 16 + 1, sizeof(unsigned));
+	s->b = (mh_int_t *) calloc(s->n_buckets / 16 + 1, sizeof(mh_int_t));
 	if (s->b == NULL) {
 		free(s->p);
 		s->p = NULL;
diff --git a/include/salloc.h b/include/salloc.h
index 773bdd08719d5938ff002774a650a4d050e33efd..562df23d08ecca108fdbcc0201712d0738b6c665 100644
--- a/include/salloc.h
+++ b/include/salloc.h
@@ -49,6 +49,8 @@ struct slab_cache_stats {
 	int64_t items;
 	int64_t bytes_used;
 	int64_t bytes_free;
+	int64_t bytes_used_real;
+	int64_t bytes_alloc_real;
 };
 
 /** Statistics on utilization of the slab allocator. */
diff --git a/src/admin.cc b/src/admin.cc
index 308a475d8762430b365f2cfca5e18258b5632587..0bc993d591d5136a79dfca3a5cb2251df2f2e478 100644
--- a/src/admin.cc
+++ b/src/admin.cc
@@ -57,6 +57,7 @@ extern "C" {
 #include "lua/init.h"
 #include "session.h"
 #include "scoped_guard.h"
+#include "box/space.h"
 
 static const char *help =
 	"available commands:" CRLF
@@ -65,6 +66,7 @@ static const char *help =
 	" - show info" CRLF
 	" - show fiber" CRLF
 	" - show configuration" CRLF
+	" - show index" CRLF
 	" - show slab" CRLF
 	" - show palloc" CRLF
 	" - show stat" CRLF
@@ -79,19 +81,21 @@ static const char *help =
 static const char *unknown_command = "unknown command. try typing help." CRLF;
 
 
-#line 83 "src/admin.cc"
+#line 85 "src/admin.cc"
 static const int admin_start = 1;
-static const int admin_first_final = 141;
+static const int admin_first_final = 145;
 static const int admin_error = 0;
 
 static const int admin_en_main = 1;
 
 
-#line 82 "src/admin.rl"
+#line 84 "src/admin.rl"
 
 
 struct salloc_stat_admin_cb_ctx {
 	int64_t total_used;
+	int64_t total_used_real;
+	int64_t total_alloc_real;
 	struct tbuf *out;
 };
 
@@ -101,16 +105,20 @@ salloc_stat_admin_cb(const struct slab_cache_stats *cstat, void *cb_ctx)
 	struct salloc_stat_admin_cb_ctx *ctx = (struct salloc_stat_admin_cb_ctx *) cb_ctx;
 
 	tbuf_printf(ctx->out,
-		    "     - { item_size: %- 5i, slabs: %- 3i, items: %- 11" PRIi64
-		    ", bytes_used: %- 12" PRIi64
-		    ", bytes_free: %- 12" PRIi64 " }" CRLF,
+		    "     - { item_size: %6i, slabs: %6i, items: %11" PRIi64
+		    ", bytes_used: %12" PRIi64 ", waste: %5.2f%%"
+		    ", bytes_free: %12" PRIi64 " }" CRLF,
 		    (int)cstat->item_size,
 		    (int)cstat->slabs,
 		    cstat->items,
 		    cstat->bytes_used,
+		    (double)(cstat->bytes_alloc_real - cstat->bytes_used_real)*100 /
+		    (cstat->bytes_alloc_real + 0.001),
 		    cstat->bytes_free);
 
 	ctx->total_used += cstat->bytes_used;
+	ctx->total_alloc_real += cstat->bytes_alloc_real;
+	ctx->total_used_real += cstat->bytes_used_real;
 	return 0;
 }
 
@@ -121,6 +129,8 @@ show_slab(struct tbuf *out)
 	struct slab_arena_stats astat;
 
 	cb_ctx.total_used = 0;
+	cb_ctx.total_used_real = 0;
+	cb_ctx.total_alloc_real = 0;
 	cb_ctx.out = out;
 
 	tbuf_printf(out, "slab statistics:\n  classes:" CRLF);
@@ -131,6 +141,11 @@ show_slab(struct tbuf *out)
 		(double)cb_ctx.total_used / astat.size * 100);
 	tbuf_printf(out, "  arena_used: %.2f%%" CRLF,
 		(double)astat.used / astat.size * 100);
+	tbuf_printf(out, "  waste: %.2f%%" CRLF,
+		    (double)(cb_ctx.total_alloc_real - cb_ctx.total_used_real) / (cb_ctx.total_alloc_real + 0.001) * 100);
+	tbuf_printf(out, "  bytes_waste: %12" PRIi64 CRLF,
+		    (int64_t)((double)cb_ctx.total_used*(cb_ctx.total_alloc_real - cb_ctx.total_used_real) /
+			      (cb_ctx.total_alloc_real + 0.001)));
 }
 
 static void
@@ -161,6 +176,32 @@ fail(struct tbuf *out, struct tbuf *err)
 	end(out);
 }
 
+static void
+index_info(struct tbuf *out)
+{
+	tbuf_printf(out, "index:" CRLF);
+	struct space_stat *stat = space_stat();
+	int sp_i = 0;
+	int64_t total_size = 0;
+	while (stat[sp_i].n >= 0) {
+		tbuf_printf(out, "  - space: %" PRIi32 CRLF, stat[sp_i].n);
+		int64_t sp_size = 0;
+		int i;
+		for (i = 0; stat[sp_i].index[i].n >= 0; ++i)
+			sp_size += stat[sp_i].index[i].memsize;
+
+		tbuf_printf(out, "    memsize: %15" PRIi64 CRLF, sp_size);
+		total_size += sp_size;
+		tbuf_printf(out, "    index: " CRLF);
+		for (i = 0; stat[sp_i].index[i].n >= 0; ++i) {
+			tbuf_printf(out, "      - { n: %3d, keys: %15" PRIi64 ", memsize: %15" PRIi64 " }" CRLF,
+				    stat[sp_i].index[i].n, stat[sp_i].index[i].keys, stat[sp_i].index[i].memsize);
+		}
+		++sp_i;
+	}
+	tbuf_printf(out, "memsize:     %15" PRIi64 CRLF, total_size);
+}
+
 static void
 tarantool_info(struct tbuf *out)
 {
@@ -223,12 +264,12 @@ admin_dispatch(struct ev_io *coio, struct iobuf *iobuf, lua_State *L)
 	p = in->pos;
 
 	
-#line 227 "src/admin.cc"
+#line 268 "src/admin.cc"
 	{
 	cs = admin_start;
 	}
 
-#line 232 "src/admin.cc"
+#line 273 "src/admin.cc"
 	{
 	if ( p == pe )
 		goto _test_eof;
@@ -291,47 +332,47 @@ case 6:
 	}
 	goto st0;
 tr13:
-#line 322 "src/admin.rl"
+#line 365 "src/admin.rl"
 	{slab_validate(); ok(out);}
-	goto st141;
+	goto st145;
 tr20:
-#line 309 "src/admin.rl"
+#line 351 "src/admin.rl"
 	{return -1;}
-	goto st141;
+	goto st145;
 tr25:
-#line 235 "src/admin.rl"
+#line 276 "src/admin.rl"
 	{
 			start(out);
 			tbuf_append(out, help, strlen(help));
 			end(out);
 		}
-	goto st141;
+	goto st145;
 tr36:
-#line 295 "src/admin.rl"
+#line 337 "src/admin.rl"
 	{strend = p;}
-#line 241 "src/admin.rl"
+#line 282 "src/admin.rl"
 	{
 			strstart[strend-strstart]='\0';
 			start(out);
 			tarantool_lua(L, out, strstart);
 			end(out);
 		}
-	goto st141;
+	goto st145;
 tr43:
-#line 248 "src/admin.rl"
+#line 289 "src/admin.rl"
 	{
 			if (reload_cfg(err))
 				fail(out, err);
 			else
 				ok(out);
 		}
-	goto st141;
+	goto st145;
 tr67:
-#line 320 "src/admin.rl"
+#line 363 "src/admin.rl"
 	{coredump(60); ok(out);}
-	goto st141;
+	goto st145;
 tr76:
-#line 255 "src/admin.rl"
+#line 296 "src/admin.rl"
 	{
 			int ret = snapshot();
 
@@ -344,11 +385,11 @@ case 6:
 				fail(out, err);
 			}
 		}
-	goto st141;
+	goto st145;
 tr98:
-#line 305 "src/admin.rl"
+#line 347 "src/admin.rl"
 	{ state = false; }
-#line 268 "src/admin.rl"
+#line 309 "src/admin.rl"
 	{
 			strstart[strend-strstart] = '\0';
 			if (errinj_set_byname(strstart, state)) {
@@ -358,11 +399,11 @@ case 6:
 				ok(out);
 			}
 		}
-	goto st141;
+	goto st145;
 tr101:
-#line 304 "src/admin.rl"
+#line 346 "src/admin.rl"
 	{ state = true; }
-#line 268 "src/admin.rl"
+#line 309 "src/admin.rl"
 	{
 			strstart[strend-strstart] = '\0';
 			if (errinj_set_byname(strstart, state)) {
@@ -372,67 +413,71 @@ case 6:
 				ok(out);
 			}
 		}
-	goto st141;
+	goto st145;
 tr117:
-#line 223 "src/admin.rl"
+#line 264 "src/admin.rl"
 	{
 			start(out);
 			show_cfg(out);
 			end(out);
 		}
-	goto st141;
+	goto st145;
 tr131:
-#line 312 "src/admin.rl"
+#line 355 "src/admin.rl"
 	{start(out); fiber_info(out); end(out);}
-	goto st141;
-tr137:
-#line 311 "src/admin.rl"
+	goto st145;
+tr139:
+#line 354 "src/admin.rl"
+	{start(out); index_info(out); end(out);}
+	goto st145;
+tr141:
+#line 353 "src/admin.rl"
 	{start(out); tarantool_info(out); end(out);}
-	goto st141;
-tr146:
-#line 229 "src/admin.rl"
+	goto st145;
+tr152:
+#line 270 "src/admin.rl"
 	{
 			start(out);
 			errinj_info(out);
 			end(out);
 		}
-	goto st141;
-tr153:
-#line 315 "src/admin.rl"
+	goto st145;
+tr159:
+#line 358 "src/admin.rl"
 	{start(out); palloc_stat(out); end(out);}
-	goto st141;
-tr164:
-#line 217 "src/admin.rl"
+	goto st145;
+tr170:
+#line 258 "src/admin.rl"
 	{
 		    start(out);
                     show_plugins_stat(out);
 		    end(out);
                 }
-	goto st141;
-tr168:
-#line 314 "src/admin.rl"
+	goto st145;
+tr174:
+#line 357 "src/admin.rl"
 	{start(out); show_slab(out); end(out);}
-	goto st141;
-tr172:
-#line 316 "src/admin.rl"
+	goto st145;
+tr178:
+#line 359 "src/admin.rl"
 	{start(out); show_stat(out);end(out);}
-	goto st141;
-st141:
+	goto st145;
+st145:
 	if ( ++p == pe )
-		goto _test_eof141;
-case 141:
-#line 425 "src/admin.cc"
+		goto _test_eof145;
+case 145:
+#line 470 "src/admin.cc"
 	goto st0;
 tr14:
-#line 322 "src/admin.rl"
+#line 365 "src/admin.rl"
 	{slab_validate(); ok(out);}
 	goto st7;
 tr21:
-#line 309 "src/admin.rl"
+#line 351 "src/admin.rl"
 	{return -1;}
 	goto st7;
 tr26:
-#line 235 "src/admin.rl"
+#line 276 "src/admin.rl"
 	{
 			start(out);
 			tbuf_append(out, help, strlen(help));
@@ -440,9 +485,9 @@ case 141:
 		}
 	goto st7;
 tr37:
-#line 295 "src/admin.rl"
+#line 337 "src/admin.rl"
 	{strend = p;}
-#line 241 "src/admin.rl"
+#line 282 "src/admin.rl"
 	{
 			strstart[strend-strstart]='\0';
 			start(out);
@@ -451,7 +496,7 @@ case 141:
 		}
 	goto st7;
 tr44:
-#line 248 "src/admin.rl"
+#line 289 "src/admin.rl"
 	{
 			if (reload_cfg(err))
 				fail(out, err);
@@ -460,11 +505,11 @@ case 141:
 		}
 	goto st7;
 tr68:
-#line 320 "src/admin.rl"
+#line 363 "src/admin.rl"
 	{coredump(60); ok(out);}
 	goto st7;
 tr77:
-#line 255 "src/admin.rl"
+#line 296 "src/admin.rl"
 	{
 			int ret = snapshot();
 
@@ -479,9 +524,9 @@ case 141:
 		}
 	goto st7;
 tr99:
-#line 305 "src/admin.rl"
+#line 347 "src/admin.rl"
 	{ state = false; }
-#line 268 "src/admin.rl"
+#line 309 "src/admin.rl"
 	{
 			strstart[strend-strstart] = '\0';
 			if (errinj_set_byname(strstart, state)) {
@@ -493,9 +538,9 @@ case 141:
 		}
 	goto st7;
 tr102:
-#line 304 "src/admin.rl"
+#line 346 "src/admin.rl"
 	{ state = true; }
-#line 268 "src/admin.rl"
+#line 309 "src/admin.rl"
 	{
 			strstart[strend-strstart] = '\0';
 			if (errinj_set_byname(strstart, state)) {
@@ -507,7 +552,7 @@ case 141:
 		}
 	goto st7;
 tr118:
-#line 223 "src/admin.rl"
+#line 264 "src/admin.rl"
 	{
 			start(out);
 			show_cfg(out);
@@ -515,48 +560,52 @@ case 141:
 		}
 	goto st7;
 tr132:
-#line 312 "src/admin.rl"
+#line 355 "src/admin.rl"
 	{start(out); fiber_info(out); end(out);}
 	goto st7;
-tr138:
-#line 311 "src/admin.rl"
+tr140:
+#line 354 "src/admin.rl"
+	{start(out); index_info(out); end(out);}
+	goto st7;
+tr142:
+#line 353 "src/admin.rl"
 	{start(out); tarantool_info(out); end(out);}
 	goto st7;
-tr147:
-#line 229 "src/admin.rl"
+tr153:
+#line 270 "src/admin.rl"
 	{
 			start(out);
 			errinj_info(out);
 			end(out);
 		}
 	goto st7;
-tr154:
-#line 315 "src/admin.rl"
+tr160:
+#line 358 "src/admin.rl"
 	{start(out); palloc_stat(out); end(out);}
 	goto st7;
-tr165:
-#line 217 "src/admin.rl"
+tr171:
+#line 258 "src/admin.rl"
 	{
 		    start(out);
                     show_plugins_stat(out);
 		    end(out);
                 }
 	goto st7;
-tr169:
-#line 314 "src/admin.rl"
+tr175:
+#line 357 "src/admin.rl"
 	{start(out); show_slab(out); end(out);}
 	goto st7;
-tr173:
-#line 316 "src/admin.rl"
+tr179:
+#line 359 "src/admin.rl"
 	{start(out); show_stat(out);end(out);}
 	goto st7;
 st7:
 	if ( ++p == pe )
 		goto _test_eof7;
 case 7:
-#line 558 "src/admin.cc"
+#line 607 "src/admin.cc"
 	if ( (*p) == 10 )
-		goto st141;
+		goto st145;
 	goto st0;
 st8:
 	if ( ++p == pe )
@@ -707,28 +756,28 @@ case 23:
 	}
 	goto tr33;
 tr33:
-#line 295 "src/admin.rl"
+#line 337 "src/admin.rl"
 	{strstart = p;}
 	goto st24;
 st24:
 	if ( ++p == pe )
 		goto _test_eof24;
 case 24:
-#line 718 "src/admin.cc"
+#line 767 "src/admin.cc"
 	switch( (*p) ) {
 		case 10: goto tr36;
 		case 13: goto tr37;
 	}
 	goto st24;
 tr34:
-#line 295 "src/admin.rl"
+#line 337 "src/admin.rl"
 	{strstart = p;}
 	goto st25;
 st25:
 	if ( ++p == pe )
 		goto _test_eof25;
 case 25:
-#line 732 "src/admin.cc"
+#line 781 "src/admin.cc"
 	switch( (*p) ) {
 		case 10: goto tr36;
 		case 13: goto tr37;
@@ -1178,28 +1227,28 @@ case 73:
 		goto tr91;
 	goto st0;
 tr91:
-#line 303 "src/admin.rl"
+#line 345 "src/admin.rl"
 	{ strstart = p; }
 	goto st74;
 st74:
 	if ( ++p == pe )
 		goto _test_eof74;
 case 74:
-#line 1189 "src/admin.cc"
+#line 1238 "src/admin.cc"
 	if ( (*p) == 32 )
 		goto tr92;
 	if ( 33 <= (*p) && (*p) <= 126 )
 		goto st74;
 	goto st0;
 tr92:
-#line 303 "src/admin.rl"
+#line 345 "src/admin.rl"
 	{ strend = p; }
 	goto st75;
 st75:
 	if ( ++p == pe )
 		goto _test_eof75;
 case 75:
-#line 1203 "src/admin.cc"
+#line 1252 "src/admin.cc"
 	switch( (*p) ) {
 		case 32: goto st75;
 		case 111: goto st76;
@@ -1316,7 +1365,7 @@ case 87:
 case 88:
 	switch( (*p) ) {
 		case 32: goto st89;
-		case 111: goto st139;
+		case 111: goto st143;
 	}
 	goto st0;
 st89:
@@ -1328,8 +1377,8 @@ case 89:
 		case 99: goto st90;
 		case 102: goto st103;
 		case 105: goto st108;
-		case 112: goto st120;
-		case 115: goto st132;
+		case 112: goto st124;
+		case 115: goto st136;
 	}
 	goto st0;
 st90:
@@ -1508,29 +1557,25 @@ case 107:
 	if ( ++p == pe )
 		goto _test_eof108;
 case 108:
-	if ( (*p) == 110 )
-		goto st109;
+	switch( (*p) ) {
+		case 100: goto st109;
+		case 110: goto st111;
+	}
 	goto st0;
 st109:
 	if ( ++p == pe )
 		goto _test_eof109;
 case 109:
-	switch( (*p) ) {
-		case 10: goto tr137;
-		case 13: goto tr138;
-		case 102: goto st110;
-		case 106: goto st112;
-		case 115: goto st115;
-	}
+	if ( (*p) == 120 )
+		goto st110;
 	goto st0;
 st110:
 	if ( ++p == pe )
 		goto _test_eof110;
 case 110:
 	switch( (*p) ) {
-		case 10: goto tr137;
-		case 13: goto tr138;
-		case 111: goto st111;
+		case 10: goto tr139;
+		case 13: goto tr140;
 	}
 	goto st0;
 st111:
@@ -1538,8 +1583,12 @@ case 110:
 		goto _test_eof111;
 case 111:
 	switch( (*p) ) {
-		case 10: goto tr137;
-		case 13: goto tr138;
+		case 10: goto tr141;
+		case 13: goto tr142;
+		case 100: goto st112;
+		case 102: goto st114;
+		case 106: goto st116;
+		case 115: goto st119;
 	}
 	goto st0;
 st112:
@@ -1547,8 +1596,9 @@ case 111:
 		goto _test_eof112;
 case 112:
 	switch( (*p) ) {
+		case 10: goto tr139;
+		case 13: goto tr140;
 		case 101: goto st113;
-		case 115: goto st115;
 	}
 	goto st0;
 st113:
@@ -1556,8 +1606,9 @@ case 112:
 		goto _test_eof113;
 case 113:
 	switch( (*p) ) {
-		case 99: goto st114;
-		case 115: goto st115;
+		case 10: goto tr139;
+		case 13: goto tr140;
+		case 120: goto st110;
 	}
 	goto st0;
 st114:
@@ -1565,8 +1616,9 @@ case 113:
 		goto _test_eof114;
 case 114:
 	switch( (*p) ) {
-		case 115: goto st115;
-		case 116: goto st116;
+		case 10: goto tr141;
+		case 13: goto tr142;
+		case 111: goto st115;
 	}
 	goto st0;
 st115:
@@ -1574,8 +1626,8 @@ case 114:
 		goto _test_eof115;
 case 115:
 	switch( (*p) ) {
-		case 10: goto tr146;
-		case 13: goto tr147;
+		case 10: goto tr141;
+		case 13: goto tr142;
 	}
 	goto st0;
 st116:
@@ -1583,8 +1635,8 @@ case 115:
 		goto _test_eof116;
 case 116:
 	switch( (*p) ) {
-		case 105: goto st117;
-		case 115: goto st115;
+		case 101: goto st117;
+		case 115: goto st119;
 	}
 	goto st0;
 st117:
@@ -1592,8 +1644,8 @@ case 116:
 		goto _test_eof117;
 case 117:
 	switch( (*p) ) {
-		case 111: goto st118;
-		case 115: goto st115;
+		case 99: goto st118;
+		case 115: goto st119;
 	}
 	goto st0;
 st118:
@@ -1601,24 +1653,26 @@ case 117:
 		goto _test_eof118;
 case 118:
 	switch( (*p) ) {
-		case 110: goto st119;
-		case 115: goto st115;
+		case 115: goto st119;
+		case 116: goto st120;
 	}
 	goto st0;
 st119:
 	if ( ++p == pe )
 		goto _test_eof119;
 case 119:
-	if ( (*p) == 115 )
-		goto st115;
+	switch( (*p) ) {
+		case 10: goto tr152;
+		case 13: goto tr153;
+	}
 	goto st0;
 st120:
 	if ( ++p == pe )
 		goto _test_eof120;
 case 120:
 	switch( (*p) ) {
-		case 97: goto st121;
-		case 108: goto st126;
+		case 105: goto st121;
+		case 115: goto st119;
 	}
 	goto st0;
 st121:
@@ -1626,9 +1680,8 @@ case 120:
 		goto _test_eof121;
 case 121:
 	switch( (*p) ) {
-		case 10: goto tr153;
-		case 13: goto tr154;
-		case 108: goto st122;
+		case 111: goto st122;
+		case 115: goto st119;
 	}
 	goto st0;
 st122:
@@ -1636,29 +1689,24 @@ case 121:
 		goto _test_eof122;
 case 122:
 	switch( (*p) ) {
-		case 10: goto tr153;
-		case 13: goto tr154;
-		case 108: goto st123;
+		case 110: goto st123;
+		case 115: goto st119;
 	}
 	goto st0;
 st123:
 	if ( ++p == pe )
 		goto _test_eof123;
 case 123:
-	switch( (*p) ) {
-		case 10: goto tr153;
-		case 13: goto tr154;
-		case 111: goto st124;
-	}
+	if ( (*p) == 115 )
+		goto st119;
 	goto st0;
 st124:
 	if ( ++p == pe )
 		goto _test_eof124;
 case 124:
 	switch( (*p) ) {
-		case 10: goto tr153;
-		case 13: goto tr154;
-		case 99: goto st125;
+		case 97: goto st125;
+		case 108: goto st130;
 	}
 	goto st0;
 st125:
@@ -1666,90 +1714,92 @@ case 124:
 		goto _test_eof125;
 case 125:
 	switch( (*p) ) {
-		case 10: goto tr153;
-		case 13: goto tr154;
+		case 10: goto tr159;
+		case 13: goto tr160;
+		case 108: goto st126;
 	}
 	goto st0;
 st126:
 	if ( ++p == pe )
 		goto _test_eof126;
 case 126:
-	if ( (*p) == 117 )
-		goto st127;
+	switch( (*p) ) {
+		case 10: goto tr159;
+		case 13: goto tr160;
+		case 108: goto st127;
+	}
 	goto st0;
 st127:
 	if ( ++p == pe )
 		goto _test_eof127;
 case 127:
-	if ( (*p) == 103 )
-		goto st128;
+	switch( (*p) ) {
+		case 10: goto tr159;
+		case 13: goto tr160;
+		case 111: goto st128;
+	}
 	goto st0;
 st128:
 	if ( ++p == pe )
 		goto _test_eof128;
 case 128:
-	if ( (*p) == 105 )
-		goto st129;
+	switch( (*p) ) {
+		case 10: goto tr159;
+		case 13: goto tr160;
+		case 99: goto st129;
+	}
 	goto st0;
 st129:
 	if ( ++p == pe )
 		goto _test_eof129;
 case 129:
-	if ( (*p) == 110 )
-		goto st130;
+	switch( (*p) ) {
+		case 10: goto tr159;
+		case 13: goto tr160;
+	}
 	goto st0;
 st130:
 	if ( ++p == pe )
 		goto _test_eof130;
 case 130:
-	if ( (*p) == 115 )
+	if ( (*p) == 117 )
 		goto st131;
 	goto st0;
 st131:
 	if ( ++p == pe )
 		goto _test_eof131;
 case 131:
-	switch( (*p) ) {
-		case 10: goto tr164;
-		case 13: goto tr165;
-	}
+	if ( (*p) == 103 )
+		goto st132;
 	goto st0;
 st132:
 	if ( ++p == pe )
 		goto _test_eof132;
 case 132:
-	switch( (*p) ) {
-		case 108: goto st133;
-		case 116: goto st136;
-	}
+	if ( (*p) == 105 )
+		goto st133;
 	goto st0;
 st133:
 	if ( ++p == pe )
 		goto _test_eof133;
 case 133:
-	switch( (*p) ) {
-		case 10: goto tr168;
-		case 13: goto tr169;
-		case 97: goto st134;
-	}
+	if ( (*p) == 110 )
+		goto st134;
 	goto st0;
 st134:
 	if ( ++p == pe )
 		goto _test_eof134;
 case 134:
-	switch( (*p) ) {
-		case 10: goto tr168;
-		case 13: goto tr169;
-		case 98: goto st135;
-	}
+	if ( (*p) == 115 )
+		goto st135;
 	goto st0;
 st135:
 	if ( ++p == pe )
 		goto _test_eof135;
 case 135:
 	switch( (*p) ) {
-		case 10: goto tr168;
-		case 13: goto tr169;
+		case 10: goto tr170;
+		case 13: goto tr171;
 	}
 	goto st0;
 st136:
@@ -1757,9 +1807,8 @@ case 135:
 		goto _test_eof136;
 case 136:
 	switch( (*p) ) {
-		case 10: goto tr172;
-		case 13: goto tr173;
-		case 97: goto st137;
+		case 108: goto st137;
+		case 116: goto st140;
 	}
 	goto st0;
 st137:
@@ -1767,9 +1816,9 @@ case 136:
 		goto _test_eof137;
 case 137:
 	switch( (*p) ) {
-		case 10: goto tr172;
-		case 13: goto tr173;
-		case 116: goto st138;
+		case 10: goto tr174;
+		case 13: goto tr175;
+		case 97: goto st138;
 	}
 	goto st0;
 st138:
@@ -1777,8 +1826,9 @@ case 137:
 		goto _test_eof138;
 case 138:
 	switch( (*p) ) {
-		case 10: goto tr172;
-		case 13: goto tr173;
+		case 10: goto tr174;
+		case 13: goto tr175;
+		case 98: goto st139;
 	}
 	goto st0;
 st139:
@@ -1786,14 +1836,52 @@ case 138:
 		goto _test_eof139;
 case 139:
 	switch( (*p) ) {
-		case 32: goto st89;
-		case 119: goto st140;
+		case 10: goto tr174;
+		case 13: goto tr175;
 	}
 	goto st0;
 st140:
 	if ( ++p == pe )
 		goto _test_eof140;
 case 140:
+	switch( (*p) ) {
+		case 10: goto tr178;
+		case 13: goto tr179;
+		case 97: goto st141;
+	}
+	goto st0;
+st141:
+	if ( ++p == pe )
+		goto _test_eof141;
+case 141:
+	switch( (*p) ) {
+		case 10: goto tr178;
+		case 13: goto tr179;
+		case 116: goto st142;
+	}
+	goto st0;
+st142:
+	if ( ++p == pe )
+		goto _test_eof142;
+case 142:
+	switch( (*p) ) {
+		case 10: goto tr178;
+		case 13: goto tr179;
+	}
+	goto st0;
+st143:
+	if ( ++p == pe )
+		goto _test_eof143;
+case 143:
+	switch( (*p) ) {
+		case 32: goto st89;
+		case 119: goto st144;
+	}
+	goto st0;
+st144:
+	if ( ++p == pe )
+		goto _test_eof144;
+case 144:
 	if ( (*p) == 32 )
 		goto st89;
 	goto st0;
@@ -1803,7 +1891,7 @@ case 140:
 	_test_eof4: cs = 4; goto _test_eof; 
 	_test_eof5: cs = 5; goto _test_eof; 
 	_test_eof6: cs = 6; goto _test_eof; 
-	_test_eof141: cs = 141; goto _test_eof; 
+	_test_eof145: cs = 145; goto _test_eof; 
 	_test_eof7: cs = 7; goto _test_eof; 
 	_test_eof8: cs = 8; goto _test_eof; 
 	_test_eof9: cs = 9; goto _test_eof; 
@@ -1938,12 +2026,16 @@ case 140:
 	_test_eof138: cs = 138; goto _test_eof; 
 	_test_eof139: cs = 139; goto _test_eof; 
 	_test_eof140: cs = 140; goto _test_eof; 
+	_test_eof141: cs = 141; goto _test_eof; 
+	_test_eof142: cs = 142; goto _test_eof; 
+	_test_eof143: cs = 143; goto _test_eof; 
+	_test_eof144: cs = 144; goto _test_eof; 
 
 	_test_eof: {}
 	_out: {}
 	}
 
-#line 328 "src/admin.rl"
+#line 371 "src/admin.rl"
 
 
 	in->pos = pe;
diff --git a/src/admin.rl b/src/admin.rl
index 59e5e06d3cfc9b68d298323fe1504546561f31aa..073461ec6fd08255c303ca0728612b16deae949c 100644
--- a/src/admin.rl
+++ b/src/admin.rl
@@ -55,6 +55,7 @@ extern "C" {
 #include "lua/init.h"
 #include "session.h"
 #include "scoped_guard.h"
+#include "box/space.h"
 
 static const char *help =
 	"available commands:" CRLF
@@ -63,6 +64,7 @@ static const char *help =
 	" - show info" CRLF
 	" - show fiber" CRLF
 	" - show configuration" CRLF
+	" - show index" CRLF
 	" - show slab" CRLF
 	" - show palloc" CRLF
 	" - show stat" CRLF
@@ -83,6 +85,8 @@ static const char *unknown_command = "unknown command. try typing help." CRLF;
 
 struct salloc_stat_admin_cb_ctx {
 	int64_t total_used;
+	int64_t total_used_real;
+	int64_t total_alloc_real;
 	struct tbuf *out;
 };
 
@@ -92,16 +96,20 @@ salloc_stat_admin_cb(const struct slab_cache_stats *cstat, void *cb_ctx)
 	struct salloc_stat_admin_cb_ctx *ctx = (struct salloc_stat_admin_cb_ctx *) cb_ctx;
 
 	tbuf_printf(ctx->out,
-		    "     - { item_size: %- 5i, slabs: %- 3i, items: %- 11" PRIi64
-		    ", bytes_used: %- 12" PRIi64
-		    ", bytes_free: %- 12" PRIi64 " }" CRLF,
+		    "     - { item_size: %6i, slabs: %6i, items: %11" PRIi64
+		    ", bytes_used: %12" PRIi64 ", waste: %5.2f%%"
+		    ", bytes_free: %12" PRIi64 " }" CRLF,
 		    (int)cstat->item_size,
 		    (int)cstat->slabs,
 		    cstat->items,
 		    cstat->bytes_used,
+		    (double)(cstat->bytes_alloc_real - cstat->bytes_used_real)*100 /
+		    (cstat->bytes_alloc_real + 0.001),
 		    cstat->bytes_free);
 
 	ctx->total_used += cstat->bytes_used;
+	ctx->total_alloc_real += cstat->bytes_alloc_real;
+	ctx->total_used_real += cstat->bytes_used_real;
 	return 0;
 }
 
@@ -112,6 +120,8 @@ show_slab(struct tbuf *out)
 	struct slab_arena_stats astat;
 
 	cb_ctx.total_used = 0;
+	cb_ctx.total_used_real = 0;
+	cb_ctx.total_alloc_real = 0;
 	cb_ctx.out = out;
 
 	tbuf_printf(out, "slab statistics:\n  classes:" CRLF);
@@ -122,6 +132,11 @@ show_slab(struct tbuf *out)
 		(double)cb_ctx.total_used / astat.size * 100);
 	tbuf_printf(out, "  arena_used: %.2f%%" CRLF,
 		(double)astat.used / astat.size * 100);
+	tbuf_printf(out, "  waste: %.2f%%" CRLF,
+		    (double)(cb_ctx.total_alloc_real - cb_ctx.total_used_real) / (cb_ctx.total_alloc_real + 0.001) * 100);
+	tbuf_printf(out, "  bytes_waste: %12" PRIi64 CRLF,
+		    (int64_t)((double)cb_ctx.total_used*(cb_ctx.total_alloc_real - cb_ctx.total_used_real) /
+			      (cb_ctx.total_alloc_real + 0.001)));
 }
 
 static void
@@ -152,6 +167,32 @@ fail(struct tbuf *out, struct tbuf *err)
 	end(out);
 }
 
+static void
+index_info(struct tbuf *out)
+{
+	tbuf_printf(out, "index:" CRLF);
+	struct space_stat *stat = space_stat();
+	int sp_i = 0;
+	int64_t total_size = 0;
+	while (stat[sp_i].n >= 0) {
+		tbuf_printf(out, "  - space: %" PRIi32 CRLF, stat[sp_i].n);
+		int64_t sp_size = 0;
+		int i;
+		for (i = 0; stat[sp_i].index[i].n >= 0; ++i)
+			sp_size += stat[sp_i].index[i].memsize;
+
+		tbuf_printf(out, "    memsize: %15" PRIi64 CRLF, sp_size);
+		total_size += sp_size;
+		tbuf_printf(out, "    index: " CRLF);
+		for (i = 0; stat[sp_i].index[i].n >= 0; ++i) {
+			tbuf_printf(out, "      - { n: %3d, keys: %15" PRIi64 ", memsize: %15" PRIi64 " }" CRLF,
+				    stat[sp_i].index[i].n, stat[sp_i].index[i].keys, stat[sp_i].index[i].memsize);
+		}
+		++sp_i;
+	}
+	tbuf_printf(out, "memsize:     %15" PRIi64 CRLF, total_size);
+}
+
 static void
 tarantool_info(struct tbuf *out)
 {
@@ -278,6 +319,7 @@ admin_dispatch(struct ev_io *coio, struct iobuf *iobuf, lua_State *L)
 		eol = "\n" | "\r\n";
 		show = "sh"("o"("w")?)?;
 		info = "in"("f"("o")?)?;
+		index = ("ind"("e"("x")?)? | "idx");
 		check = "ch"("e"("c"("k")?)?)?;
 		configuration = "co"("n"("f"("i"("g"("u"("r"("a"("t"("i"("o"("n")?)?)?)?)?)?)?)?)?)?)?;
 		fiber = "fi"("b"("e"("r")?)?)?;
@@ -309,6 +351,7 @@ admin_dispatch(struct ev_io *coio, struct iobuf *iobuf, lua_State *L)
 			    exit			%{return -1;}					|
 			    lua  " "+ string		%lua						|
 			    show " "+ info		%{start(out); tarantool_info(out); end(out);}	|
+			    show " "+ index		%{start(out); index_info(out); end(out);}	|
 			    show " "+ fiber		%{start(out); fiber_info(out); end(out);}	|
 			    show " "+ configuration 	%show_configuration				|
 			    show " "+ slab		%{start(out); show_slab(out); end(out);}	|
diff --git a/src/box/bitset_index.cc b/src/box/bitset_index.cc
index c22b209661322a40f834b9898e38bb4815c6b5ac..9c780a307c4d5acd002ff5d89a0a517678feae21 100644
--- a/src/box/bitset_index.cc
+++ b/src/box/bitset_index.cc
@@ -146,6 +146,12 @@ BitsetIndex::size() const
 	return bitset_index_size(&index);
 }
 
+size_t
+BitsetIndex::memsize() const
+{
+	return 0;
+}
+
 struct tuple *
 BitsetIndex::min() const
 {
diff --git a/src/box/bitset_index.h b/src/box/bitset_index.h
index f78236f5ff50642935f77b862784173541d9ae06..163ea52599d45d46d2c70d5f71d9f6974e5fe8ce 100644
--- a/src/box/bitset_index.h
+++ b/src/box/bitset_index.h
@@ -60,6 +60,7 @@ class BitsetIndex: public Index {
 				      struct tuple *new_tuple,
 				      enum dup_replace_mode mode);
 
+        virtual size_t memsize() const;
 	virtual struct iterator *allocIterator() const;
 	virtual void initIterator(struct iterator *iterator,
 				  enum iterator_type type,
diff --git a/src/box/hash_index.cc b/src/box/hash_index.cc
index c5f3277cdf9e877602a712d3331e783a6d36bdbd..e076f4633f10487979dd7b546c005464d7dd52f0 100644
--- a/src/box/hash_index.cc
+++ b/src/box/hash_index.cc
@@ -237,6 +237,11 @@ HashIndex::size() const
 	return mh_size(hash);
 }
 
+size_t
+HashIndex::memsize() const
+{
+        return mh_index_memsize(hash);
+}
 
 struct tuple *
 HashIndex::min() const
diff --git a/src/box/hash_index.h b/src/box/hash_index.h
index 3fdb7d54f78841ec7197009a46b920bf43e2fb71..5fb09a02923d7dc11b0531fcc61dea11a7982e35 100644
--- a/src/box/hash_index.h
+++ b/src/box/hash_index.h
@@ -57,6 +57,7 @@ class HashIndex: public Index {
 				  const char *key, uint32_t part_count) const;
 
 	virtual void reserve(uint32_t n_tuples);
+	virtual size_t memsize() const;
 
 protected:
 	struct mh_index_t *hash;
diff --git a/src/box/index.h b/src/box/index.h
index 646562b84fec215097c3133d372369cf5fe2f964..67cfc0eb0a41e44598700e9c3ddbd14b5bbf468b 100644
--- a/src/box/index.h
+++ b/src/box/index.h
@@ -177,6 +177,7 @@ class Index: public Object {
 	virtual struct tuple *replace(struct tuple *old_tuple,
 				      struct tuple *new_tuple,
 				      enum dup_replace_mode mode) = 0;
+	virtual size_t memsize() const = 0;
 	/**
 	 * Create a structure to represent an iterator. Must be
 	 * initialized separately.
diff --git a/src/box/space.cc b/src/box/space.cc
index fbff6095e91c71368684d31944a08b3a96067ce6..bbf8a5a7bb756ebddb79ab92b749524d8082221c 100644
--- a/src/box/space.cc
+++ b/src/box/space.cc
@@ -55,6 +55,34 @@ static bool secondary_indexes_enabled = false;
  */
 static bool primary_indexes_enabled = false;
 
+struct space_stat *
+space_stat()
+{
+	static __thread struct space_stat space_stat[SPACE_STAT_MAX];
+
+	int sp_i = 0;
+	mh_int_t i;
+	mh_foreach(spaces, i) {
+		struct space *sp = (struct space *)
+			mh_i32ptr_node(spaces, i)->val;
+		space_stat[sp_i].n = space_n(sp);
+		int n = sp->key_count;
+		int i = 0;
+		for (; i < n; i++) {
+			Index *index = sp->index[i];
+			space_stat[sp_i].index[i].n       = i;
+			space_stat[sp_i].index[i].keys    = index->size();
+			space_stat[sp_i].index[i].memsize = index->memsize();
+		}
+		space_stat[sp_i].index[i].n = -1;
+		++sp_i;
+		if (sp_i + 1 >= SPACE_STAT_MAX)
+			break;
+	}
+	space_stat[sp_i].n = -1;
+	return space_stat;
+}
+
 
 static void
 space_create(struct space *space, uint32_t space_no,
diff --git a/src/box/space.h b/src/box/space.h
index 8bd6aff5f5a649c09413275b133ce8c67f2b9639..abe8eae101a607fa74f2314d3a03e4465acdb0b8 100644
--- a/src/box/space.h
+++ b/src/box/space.h
@@ -246,4 +246,20 @@ index_find(struct space *sp, uint32_t index_no)
 	return idx;
 }
 
+#define SPACE_STAT_MAX 256
+
+struct index_stat {
+	int32_t n;
+	int64_t keys;
+	int64_t memsize;
+};
+
+struct space_stat {
+	int32_t n;
+	struct index_stat index[SPACE_STAT_MAX];
+};
+
+struct space_stat *
+space_stat();
+
 #endif /* TARANTOOL_BOX_SPACE_H_INCLUDED */
diff --git a/src/box/tree_index.cc b/src/box/tree_index.cc
index b5a4df66eb8323a8c93f5e40cfe8961bd449e079..30842b49721bdc580dc4e14ed0f51dd14109ba68 100644
--- a/src/box/tree_index.cc
+++ b/src/box/tree_index.cc
@@ -224,6 +224,12 @@ TreeIndex::size() const
 	return tree.size;
 }
 
+size_t
+TreeIndex::memsize() const
+{
+        return tree.size * (8 + sizeof(struct sptree_index_node));
+}
+
 struct tuple *
 TreeIndex::min() const
 {
diff --git a/src/box/tree_index.h b/src/box/tree_index.h
index c19380303fddaa3d3594bd61e8d6381e675147ed..04a4a9dd603dda49013764b63edc62b1b350542e 100644
--- a/src/box/tree_index.h
+++ b/src/box/tree_index.h
@@ -56,6 +56,7 @@ class TreeIndex: public Index {
 				      struct tuple *new_tuple,
 				      enum dup_replace_mode mode);
 
+	virtual size_t memsize() const;
 	virtual struct iterator *allocIterator() const;
 	virtual void initIterator(struct iterator *iterator,
 				  enum iterator_type type,
diff --git a/src/salloc.cc b/src/salloc.cc
index 14108bf31c7f02647062523d83256ec989d055de..8f48002e1ae94cd25f8b373149103d1d269f27b6 100644
--- a/src/salloc.cc
+++ b/src/salloc.cc
@@ -75,6 +75,8 @@ struct slab {
 	uint32_t magic;
 	size_t used;
 	size_t items;
+	size_t used_real;
+	size_t alloc_real;
 	struct item_slist_head free;
 	struct slab_cache *cache;
 	void *brk;
@@ -396,6 +398,8 @@ salloc(size_t size, const char *what)
 	if (fully_formatted(slab) && SLIST_EMPTY(&slab->free))
 		TAILQ_REMOVE(&cache->free_slabs, slab, cache_free_link);
 
+	slab->used_real += size + sizeof(red_zone);
+	slab->alloc_real += cache->item_size + sizeof(red_zone);
 	slab->used += cache->item_size + sizeof(red_zone);
 	slab->items += 1;
 
@@ -475,6 +479,8 @@ salloc_stat(salloc_stat_cb cb, struct slab_arena_stats *astat, void *cb_ctx)
 				st.bytes_free -= sizeof(struct slab);
 				st.bytes_used += sizeof(struct slab);
 				st.bytes_used += slab->used;
+				st.bytes_alloc_real += slab->alloc_real + sizeof(struct slab);
+				st.bytes_used_real += slab->used_real + sizeof(struct slab);
 			}
 			st.item_size = slab_caches[i].item_size;
 
diff --git a/test/box/admin.result b/test/box/admin.result
index 5e9a0f43e4c6ab651ce7c3f1beb1b13e11a4aa26..ee4390105a19c74ea33c142962006d72b87fcc61 100644
--- a/test/box/admin.result
+++ b/test/box/admin.result
@@ -17,6 +17,7 @@ available commands:
  - show info
  - show fiber
  - show configuration
+ - show index
  - show slab
  - show palloc
  - show stat