diff --git a/client/tarantool_checksum/tc_file.c b/client/tarantool_checksum/tc_file.c
index 3e69249628b14eeb519f18e8428295de6aa243ea..fff98356c92e4d978f89803c83cb8dfb8809a902 100644
--- a/client/tarantool_checksum/tc_file.c
+++ b/client/tarantool_checksum/tc_file.c
@@ -193,8 +193,8 @@ int tc_file_load(struct tc_spaces *s, char *file,
 				return -1;
 			}
 			const struct tc_key *node = k;
-			mh_int_t pos = mh_pk_put(space->hash_log, &node,
-						  space, space, NULL);
+			mh_int_t pos = mh_pk_put(space->hash_log, &node, NULL,
+						 space, space);
 			if (pos == mh_end(space->hash_log)) {
 				fclose(f);
 				return -1;
@@ -211,7 +211,7 @@ int tc_file_load(struct tc_spaces *s, char *file,
 			}
 			const struct tc_key *node = k;
 			mh_int_t pos = mh_pk_put(space->hash_snap, &node,
-						 space, space, NULL);
+						 NULL, space, space);
 			if (pos == mh_end(space->hash_log)) {
 				fclose(f);
 				return -1;
diff --git a/client/tarantool_checksum/tc_generate.c b/client/tarantool_checksum/tc_generate.c
index 2683a217922305815fdb299ebd74ba6ab997afaa..a11677d7e3556367392ad4e38570b6ef2e4381a0 100644
--- a/client/tarantool_checksum/tc_generate.c
+++ b/client/tarantool_checksum/tc_generate.c
@@ -226,7 +226,7 @@ tc_generate_entry(struct tc_spaces *s, struct tnt_request *r)
 	}
 	/* 3. put into hash */
 	const struct tc_key *node = k;
-	mh_int_t pos = mh_pk_put(space->hash_log, &node, space, space, NULL);
+	mh_int_t pos = mh_pk_put(space->hash_log, &node, NULL, space, space);
 	if (pos == mh_end(space->hash_log)) {
 		free(k);
 		return -1;
@@ -380,8 +380,8 @@ tc_generate_snaprow(struct tc_spaces *s, struct tnt_iter_storage *is,
 	if (v == NULL) {
 		k->crc = crc32c(0, (unsigned char*)is->t.data, is->t.size);
 		const struct tc_key *node = k;
-		mh_int_t pos = mh_pk_put(space->hash_snap, &node,
-					 space, space, NULL);
+		mh_int_t pos = mh_pk_put(space->hash_snap, &node, NULL,
+					 space, space);
 		if (pos == mh_end(space->hash_snap)) {
 			free(k);
 			return -1;
diff --git a/client/tarantool_checksum/tc_space.c b/client/tarantool_checksum/tc_space.c
index 1d4ea1310dd34711ed9fe3176300fe76fccb0436..d32e060414e39310396e8433a5818b4d9ed9eafe 100644
--- a/client/tarantool_checksum/tc_space.c
+++ b/client/tarantool_checksum/tc_space.c
@@ -92,10 +92,9 @@ struct tc_space *tc_space_create(struct tc_spaces *s, uint32_t id) {
 	space->id = id;
 	space->hash_log = mh_pk_new();
 	space->hash_snap = mh_pk_new();
-	int ret;
 
 	const struct mh_u32ptr_node_t node = { .key = space->id, .val = space };
-	mh_u32ptr_put(s->t, &node, space, space, &ret);
+	mh_u32ptr_put(s->t, &node, NULL, space, space);
 	return space;
 }
 
diff --git a/include/mhash.h b/include/mhash.h
index e48a71d7b0ceb2f1c7353268996c4d72c29d4eb9..9dd7ed8db38557c7d41409104c50e3935312201f 100644
--- a/include/mhash.h
+++ b/include/mhash.h
@@ -234,9 +234,18 @@ _mh(put_slot)(struct _mh(t) *h, const mh_node_t *node,
 	return save_i;
 }
 
+/**
+ * Find a node in the hash and replace it with a new value.
+ * Save the old node in ret pointer, if it is provided.
+ * If the old node didn't exist, just insert the new node.
+ *
+ * @retval != mh_end()   pos of the new node, ret is either NULL
+ *                       or copy of the old node
+ * @retval  mh_end()     out of memory, ret is unchanged.
+ */
 static inline mh_int_t
-_mh(put)(struct _mh(t) *h, const mh_node_t *node,
-	 mh_hash_arg_t hash_arg, mh_eq_arg_t eq_arg, int *ret)
+_mh(put)(struct _mh(t) *h, const mh_node_t *node, mh_node_t **ret,
+	 mh_hash_arg_t hash_arg, mh_eq_arg_t eq_arg)
 {
 	mh_int_t x = mh_end(h);
 	if (h->size == h->n_buckets)
@@ -251,7 +260,7 @@ _mh(put)(struct _mh(t) *h, const mh_node_t *node,
 			goto put_done;
 	}
 	if (h->resize_position)
-		_mh(put)(h->shadow, node, hash_arg, eq_arg, NULL);
+		_mh(put)(h->shadow, node, NULL, hash_arg, eq_arg);
 #else
 	if (mh_unlikely(h->n_dirty >= h->upper_bound)) {
 		if (_mh(start_resize)(h, h->n_buckets + 1, h->size,
@@ -262,8 +271,6 @@ _mh(put)(struct _mh(t) *h, const mh_node_t *node,
 
 	x = put_slot(h, node, hash_arg, eq_arg);
 	int exist = mh_exist(h, x);
-	if (ret)
-		*ret = !exist;
 
 	if (!exist) {
 		/* add new */
@@ -273,7 +280,11 @@ _mh(put)(struct _mh(t) *h, const mh_node_t *node,
 			h->n_dirty++;
 
 		memcpy(&(h->p[x]), node, sizeof(mh_node_t));
+		if (ret)
+			*ret = NULL;
 	} else {
+		if (ret)
+			memcpy(*ret, &(h->p[x]), sizeof(mh_node_t));
 		/* replace old */
 		memcpy(&(h->p[x]), node, sizeof(mh_node_t));
 	}
@@ -282,37 +293,6 @@ _mh(put)(struct _mh(t) *h, const mh_node_t *node,
 	return x;
 }
 
-
-/**
- * Find a node in the hash and replace it with a new value.
- * Save the old node in p_old pointer, if it is provided.
- * If the old node didn't exist, just insert the new node.
- */
-static inline mh_int_t
-_mh(replace)(struct _mh(t) *h, const mh_node_t *node, mh_node_t **p_old,
-	 mh_hash_arg_t hash_arg, mh_eq_arg_t eq_arg)
-{
-	mh_int_t k = _mh(get)(h, node, hash_arg, eq_arg);
-	if (k == mh_end(h)) {
-		/* No such node yet: insert a new one. */
-		if (p_old) {
-			*p_old = NULL;
-		}
-		return _mh(put)(h, node, hash_arg, eq_arg, NULL);
-	} else {
-		/*
-		 * Maintain uniqueness: replace the old node
-		 * with a new value.
-		 */
-		if (p_old) {
-			/* Save the old value. */
-			memcpy(*p_old, &(h->p[k]), sizeof(mh_node_t));
-		}
-		memcpy(&(h->p[k]), node, sizeof(mh_node_t));
-		return k;
-	}
-}
-
 static inline void
 _mh(del)(struct _mh(t) *h, mh_int_t x,
 	 mh_hash_arg_t hash_arg, mh_eq_arg_t eq_arg)
diff --git a/src/box/hash_index.m b/src/box/hash_index.m
index d72fed45c241ce04639ca0e8ce25216c257f27cb..221d0eab64a780f87fa30e16275d1ac020ba9fa4 100644
--- a/src/box/hash_index.m
+++ b/src/box/hash_index.m
@@ -337,8 +337,8 @@ int32_tuple_to_node(struct tuple *tuple, struct key_def *key_def)
 	if (new_tuple) {
 		struct mh_i32ptr_node_t *dup_node = &old_node;
 		new_node = int32_tuple_to_node(new_tuple, key_def);
-		mh_int_t pos = mh_i32ptr_replace(int_hash, &new_node,
-						 &dup_node, NULL, NULL);
+		mh_int_t pos = mh_i32ptr_put(int_hash, &new_node,
+					     &dup_node, NULL, NULL);
 
 		ERROR_INJECT(ERRINJ_INDEX_ALLOC,
 		{
@@ -356,8 +356,8 @@ int32_tuple_to_node(struct tuple *tuple, struct key_def *key_def)
 		if (errcode) {
 			mh_i32ptr_remove(int_hash, &new_node, NULL, NULL);
 			if (dup_node) {
-				pos = mh_i32ptr_replace(int_hash, dup_node,
-							NULL, NULL, NULL);
+				pos = mh_i32ptr_put(int_hash, dup_node,
+						    NULL, NULL, NULL);
 				if (pos == mh_end(int_hash)) {
 					panic("Failed to allocate memory in "
 					      "recover of int hash");
@@ -500,8 +500,8 @@ int64_tuple_to_node(struct tuple *tuple, struct key_def *key_def)
 	if (new_tuple) {
 		struct mh_i64ptr_node_t *dup_node = &old_node;
 		new_node = int64_tuple_to_node(new_tuple, key_def);
-		mh_int_t pos = mh_i64ptr_replace(int64_hash, &new_node,
-						 &dup_node, NULL, NULL);
+		mh_int_t pos = mh_i64ptr_put(int64_hash, &new_node,
+					     &dup_node, NULL, NULL);
 
 		ERROR_INJECT(ERRINJ_INDEX_ALLOC,
 		{
@@ -518,8 +518,8 @@ int64_tuple_to_node(struct tuple *tuple, struct key_def *key_def)
 		if (errcode) {
 			mh_i64ptr_remove(int64_hash, &new_node, NULL, NULL);
 			if (dup_node) {
-				pos = mh_i64ptr_replace(int64_hash, dup_node,
-							NULL, NULL, NULL);
+				pos = mh_i64ptr_put(int64_hash, dup_node,
+						    NULL, NULL, NULL);
 				if (pos == mh_end(int64_hash)) {
 					panic("Failed to allocate memory in "
 					      "recover of int64 hash");
@@ -660,8 +660,8 @@ lstrptr_tuple_to_node(struct tuple *tuple, struct key_def *key_def)
 	if (new_tuple) {
 		struct mh_lstrptr_node_t *dup_node = &old_node;
 		new_node = lstrptr_tuple_to_node(new_tuple, key_def);
-		mh_int_t pos = mh_lstrptr_replace(str_hash, &new_node,
-						  &dup_node, NULL, NULL);
+		mh_int_t pos = mh_lstrptr_put(str_hash, &new_node,
+					      &dup_node, NULL, NULL);
 
 		ERROR_INJECT(ERRINJ_INDEX_ALLOC,
 		{
@@ -679,8 +679,8 @@ lstrptr_tuple_to_node(struct tuple *tuple, struct key_def *key_def)
 		if (errcode) {
 			mh_lstrptr_remove(str_hash, &new_node, NULL, NULL);
 			if (dup_node) {
-				pos = mh_lstrptr_replace(str_hash, dup_node,
-							 NULL, NULL, NULL);
+				pos = mh_lstrptr_put(str_hash, dup_node,
+						     NULL, NULL, NULL);
 				if (pos == mh_end(str_hash)) {
 					panic("Failed to allocate memory in "
 					      "recover of str hash");
diff --git a/src/fiber.m b/src/fiber.m
index fc9ee2a088383b7c106c654acc1fe7bc56e1e689..6bdae1ae9ff8b2f3adaf9c6e2cb7d39e07154c21 100644
--- a/src/fiber.m
+++ b/src/fiber.m
@@ -312,9 +312,8 @@ fiber_find(int fid)
 static void
 register_fid(struct fiber *fiber)
 {
-	int ret;
 	struct mh_i32ptr_node_t node = { .key = fiber -> fid, .val = fiber };
-	mh_i32ptr_put(fiber_registry, &node, NULL, NULL, &ret);
+	mh_i32ptr_put(fiber_registry, &node, NULL, NULL, NULL);
 }
 
 static void
diff --git a/src/session.m b/src/session.m
index 0d0ec2e942387682414210fab29bde7076f029dd..9640fe8832ea10a888f3665d628f40e16eddd478 100644
--- a/src/session.m
+++ b/src/session.m
@@ -47,12 +47,11 @@ session_create(int fd)
 		;
 
 	uint32_t sid = sid_max;
-	int ret;
 	struct mh_i32ptr_node_t node = {
 		.key = sid, .val =  (void *) (intptr_t) fd
 	};
 
-	mh_int_t k = mh_i32ptr_put(session_registry, &node, NULL, NULL, &ret);
+	mh_int_t k = mh_i32ptr_put(session_registry, &node, NULL, NULL, NULL);
 
 	if (k == mh_end(session_registry)) {
 		tnt_raise(ClientError, :ER_MEMORY_ISSUE,