diff --git a/src/lib/small/mempool.c b/src/lib/small/mempool.c
index ae32cdf9471197211c5b32cec8fbc25bc1a6c17d..83a1dc3cd7628be0f2f7ead5aa117079609e26d6 100644
--- a/src/lib/small/mempool.c
+++ b/src/lib/small/mempool.c
@@ -50,16 +50,13 @@ mslab_create(struct mslab *slab, struct mempool *pool)
 	slab->pool = pool;
 	slab->free_idx = 0;
 	slab->free_list = 0;
-	/* A bit is set if a slot is free. */
-	memset(slab->map, 0xFF, sizeof(slab->map[0]) * pool->mapsize);
 }
 
 /** Beginning of object data in the slab. */
 static inline void *
 mslab_offset(struct mslab *slab)
 {
-	return (char *) slab + mslab_sizeof() +
-		MEMPOOL_MAP_SIZEOF * slab->pool->mapsize;
+	return (char *) slab + slab->pool->objoffset;
 }
 
 /** Pointer to an object from object index. */
@@ -69,40 +66,20 @@ mslab_obj(struct mslab *slab, uint32_t idx)
 	return mslab_offset(slab) + idx * slab->pool->objsize;
 }
 
-/** Object index from pointer to object */
-static inline uint32_t
-mslab_idx(struct mslab *slab, void *ptr)
-{
-	/*
-	 * @todo: consider optimizing this division with
-	 * multiply-shift method described in Hacker's Delight,
-	 * p. 187.
-	 */
-	return ((uint32_t)(ptr - mslab_offset(slab)))/slab->pool->objsize;
-}
-
 void *
 mslab_alloc(struct mslab *slab)
 {
 	assert(slab->nfree);
 	void *result;
-	uint32_t idx;
 	if (slab->free_list) {
 		/* Recycle an object from the garbage pool. */
-		idx = mslab_idx(slab, slab->free_list);
 		result = slab->free_list;
 		slab->free_list = *(void **)slab->free_list;
 	} else {
 		/* Use an object from the "untouched" area of the slab. */
-		idx = slab->free_idx++;
-		result = mslab_obj(slab, idx);
+		result = mslab_obj(slab, slab->free_idx++);
 	}
 
-	/* Mark the position as occupied. */
-	const uint32_t slot = idx / MEMPOOL_MAP_BIT;
-	const uint32_t bit_no = idx & (MEMPOOL_MAP_BIT-1);
-	slab->map[slot] ^= ((mbitmap_t) 1) << (mbitmap_t) bit_no;
-
 	/* If the slab is full, remove it from the rb tree. */
 	if (--slab->nfree == 0)
 		mslab_tree_remove(&slab->pool->free_slabs, slab);
@@ -117,13 +94,6 @@ mslab_free(struct mempool *pool, struct mslab *slab, void *ptr)
 	*(void **)ptr = slab->free_list;
 	slab->free_list = ptr;
 
-	uint32_t idx = mslab_idx(slab, ptr);
-
-	/* Mark the position as free. */
-	const uint32_t slot = idx / MEMPOOL_MAP_BIT;
-	const uint32_t bit_no = idx & (MEMPOOL_MAP_BIT-1);
-	slab->map[slot] |= ((mbitmap_t) 1) << bit_no;
-
 	slab->nfree++;
 
 	if (slab->nfree == 1) {
@@ -161,35 +131,12 @@ mempool_create_with_order(struct mempool *pool, struct slab_cache *cache,
 	pool->spare = NULL;
 	pool->objsize = objsize;
 	pool->slab_order = order;
-	/* Account for slab meta. */
-	uint32_t slab_size = slab_order_size(pool->cache, pool->slab_order) -
-		mslab_sizeof();
+	/* Total size of slab */
+	uint32_t slab_size = slab_order_size(pool->cache, pool->slab_order);
 	/* Calculate how many objects will actually fit in a slab. */
-	/*
-	 * We have 'slab_size' bytes for X objects and
-	 * X / 8 bits in free/used array.
-	 *
-	 * Therefore the formula for objcount is:
-	 *
-	 * X * objsize + X/8 = slab_size
-	 * X = (8 * slab_size)/(8 * objsize + 1)
-	 */
-	uint32_t objcount = (CHAR_BIT * slab_size)/(CHAR_BIT * objsize + 1);
-	/* How many elements of slab->map can map objcount. */
-	assert(objcount);
-	uint32_t mapsize = (objcount + MEMPOOL_MAP_BIT - 1)/MEMPOOL_MAP_BIT;
-	/* Adjust the result of integer division, which may be too large. */
-	while (objcount * objsize + mapsize * MEMPOOL_MAP_SIZEOF > slab_size) {
-		objcount--;
-		mapsize = (objcount + MEMPOOL_MAP_BIT - 1)/MEMPOOL_MAP_BIT;
-	}
-	assert(mapsize * MEMPOOL_MAP_BIT >= objcount);
-	/* The wasted memory should be under objsize */
-	assert(slab_size - objcount * objsize -
-	       mapsize * MEMPOOL_MAP_SIZEOF < objsize ||
-	       mapsize * MEMPOOL_MAP_BIT == objcount);
-	pool->objcount = objcount;
-	pool->mapsize = mapsize;
+	pool->objcount = (slab_size - mslab_sizeof()) / objsize;
+	assert(pool->objcount);
+	pool->objoffset = slab_size - pool->objcount * pool->objsize;
 }
 
 void
diff --git a/src/lib/small/mempool.h b/src/lib/small/mempool.h
index 8ce0056953d9c84be0f0f55117709a8ef1d6ad99..a012aa175031b3bc32c6eb6e9415d5995a2cac8d 100644
--- a/src/lib/small/mempool.h
+++ b/src/lib/small/mempool.h
@@ -70,26 +70,6 @@ extern "C" {
  * error in case of failure.
  */
 
-typedef unsigned long mbitmap_t;
-
-enum {
-	/**
-	 * At least this many bytes must be reserved
-	 * for free/occupied object bit map.
-	 */
-	MEMPOOL_MAP_SIZEOF = sizeof(mbitmap_t),
-	/**
-	 * How many bits per bitmap, i.e. how many objects
-	 * a single bitmap can map.
-	 */
-	MEMPOOL_MAP_BIT = MEMPOOL_MAP_SIZEOF * CHAR_BIT,
-	/** Mempool slab has to contain at least this many
-	 * objects, to ensure that overhead on bitmaps
-	 * for free/used objects is small.
-	 */
-	MEMPOOL_OBJ_MIN = 2 * MEMPOOL_MAP_BIT
-};
-
 /** mslab - a standard slab formatted to store objects of equal size. */
 struct mslab {
 	struct slab slab;
@@ -103,18 +83,14 @@ struct mslab {
 	rb_node(struct mslab) node;
 	/* Reference to the owning pool. */
 	struct mempool *pool;
-	/**
-	 * A bitmap for free used/objects in the slab.
-	 * A bitmap rather than a free list is used since:
-	 * - this tends to keep allocations close to the
-	 *   beginning of the slab, which is better for
-	 *   cache locality
-	 * - it makes it possible to iterate over all
-	 *   objects in a slab.
-	 */
-	mbitmap_t map[0];
 };
 
+/**
+ * Mempool will try to allocate blocks large enough to have overhead
+ * less than specified below
+ */
+static const double expected_overhead_max = 0.05;
+
 static inline uint32_t
 mslab_sizeof()
 {
@@ -129,7 +105,7 @@ static inline uint32_t
 mempool_objsize_max(uint32_t slab_size)
 {
 	/* Fit at least 4 objects in a slab, aligned by pointer size. */
-	return ((slab_size - mslab_sizeof() - MEMPOOL_MAP_SIZEOF)/4) &
+	return ((slab_size - mslab_sizeof()) / 4) &
 		 ~(sizeof(intptr_t) - 1);
 }
 
@@ -172,11 +148,8 @@ struct mempool
 	uint8_t slab_order;
 	/** How many objects can fit in a slab. */
 	uint32_t objcount;
-	/**
-	 * How many bytes of the slab are reserved for
-	 * slab map.
-	 */
-	uint32_t mapsize;
+	/** Offset from beginning of slab to the first object */
+	uint32_t objoffset;
 };
 
 /** Allocation statistics. */
@@ -218,8 +191,10 @@ static inline void
 mempool_create(struct mempool *pool, struct slab_cache *cache,
 	       uint32_t objsize)
 {
-	/* Keep size-induced internal fragmentation within limits. */
-	size_t slab_size_min = objsize * MEMPOOL_OBJ_MIN;
+	size_t expected_loss = objsize > sizeof(struct mslab)
+		? objsize : sizeof(struct mslab);
+	size_t slab_size_min = (size_t)(expected_loss / expected_overhead_max);
+
 	/*
 	 * Calculate the amount of usable space in a slab.
 	 * @note: this asserts that slab_size_min is less than
diff --git a/src/lib/small/slab_cache.h b/src/lib/small/slab_cache.h
index 8111908302b5eddea80174d78ddb260886f60aa4..892872e617ffc4a8d6052f441651b0f70f3d5595 100644
--- a/src/lib/small/slab_cache.h
+++ b/src/lib/small/slab_cache.h
@@ -211,8 +211,8 @@ slab_order(struct slab_cache *cache, size_t size)
 	if (size > cache->arena->slab_size)
 		return cache->order_max + 1;
 
-	return (uint8_t) (CHAR_BIT * sizeof(uint32_t) -
-			  __builtin_clz((uint32_t) size - 1) -
+	return (uint8_t) (CHAR_BIT * sizeof(unsigned) -
+			  __builtin_clz((unsigned) size - 1) -
 			  cache->order0_size_lb);
 }
 
diff --git a/test/unit/mempool.c b/test/unit/mempool.c
index 90c72d5f53b09e61969d2ee2ffa1208f88cc861f..d8a1a308b531db5f1f2eef129646bf01977cced4 100644
--- a/test/unit/mempool.c
+++ b/test/unit/mempool.c
@@ -93,6 +93,25 @@ mempool_basic()
 	footer();
 }
 
+void
+mempool_aligh()
+{
+	header();
+
+	for (uint32_t size = OBJSIZE_MIN; size < OBJSIZE_MAX; size <<= 1) {
+		mempool_create(&pool, &cache, size);
+		for (uint32_t i = 0; i < 32; i++) {
+			void *ptr = mempool_alloc_nothrow(&pool);
+			uintptr_t addr = (uintptr_t)ptr;
+			if (addr % size)
+				fail("aligment", "wrong");
+		}
+		mempool_destroy(&pool);
+	}
+
+	footer();
+}
+
 int main()
 {
 	seed = time(0);
@@ -111,5 +130,7 @@ int main()
 
 	mempool_basic();
 
+	mempool_aligh();
+
 	slab_cache_destroy(&cache);
 }
diff --git a/test/unit/mempool.result b/test/unit/mempool.result
index 54b455e7f18e24afe25528b83b211b52c4f2bb6c..5195759382c3b9600299e684d1bf460230fe7c26 100644
--- a/test/unit/mempool.result
+++ b/test/unit/mempool.result
@@ -1,3 +1,5 @@
 	*** mempool_basic ***
 	*** mempool_basic: done ***
+ 	*** mempool_aligh ***
+	*** mempool_aligh: done ***
  
\ No newline at end of file