diff --git a/include/lua/init.h b/include/lua/init.h
index 382516efc3490aca83809e71cba52705a6335b07..0088d33046c828cb7c29ce8a197dfada94116ed3 100644
--- a/include/lua/init.h
+++ b/include/lua/init.h
@@ -28,6 +28,7 @@
  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+#include <stddef.h>
 #include <inttypes.h>
 
 struct lua_State;
@@ -119,5 +120,13 @@ int luaL_pushnumber64(struct lua_State *L, uint64_t val);
 struct tbuf;
 void show_plugins_stat(struct tbuf *out);
 
+/**
+ * @brief A palloc-like wrapper to allocate memory using lua_newuserdata
+ * @param ctx lua_State
+ * @param size a number of bytes to allocate
+ * @return a pointer to the allocated memory
+ */
+void *
+lua_region_alloc(void *ctx, size_t size);
 
 #endif /* INCLUDES_TARANTOOL_LUA_H */
diff --git a/include/palloc.h b/include/palloc.h
index d1f89569e73a1091a77fa8bd8c3255318f516d1a..c108a42950dd7e8f2151c968ae1b13b5d5b99339 100644
--- a/include/palloc.h
+++ b/include/palloc.h
@@ -61,6 +61,12 @@ size_t palloc_allocated(struct palloc_pool *);
 
 void palloc_stat(struct tbuf *buf);
 
+static inline void *
+palloc_region_alloc(void *ctx, size_t size)
+{
+	return palloc((struct palloc_pool *) ctx, size);
+}
+
 #if defined(__cplusplus)
 } /* extern "C" */
 #endif /* defined(__cplusplus) */
diff --git a/src/box/box_lua.cc b/src/box/box_lua.cc
index 21503c9928c71d8d945b497609712265f5000660..761d0e5f17cc95291d33ed691ba04f7551117974 100644
--- a/src/box/box_lua.cc
+++ b/src/box/box_lua.cc
@@ -353,7 +353,10 @@ lbox_tuple_transform(struct lua_State *L)
 	const char *expr = lua_tolstring(L, -1, &expr_len);
 
 	/* Execute tuple_update */
-	struct tuple *new_tuple = tuple_update(tuple, expr, expr + expr_len);
+	struct tuple *new_tuple = tuple_update(lua_region_alloc, L,
+					       tuple, expr, expr + expr_len);
+	/* Cleanup memory allocated by lua_region_alloc */
+	lua_settop(L, 0);
 	lbox_pushtuple(L, new_tuple);
 	return 1;
 }
diff --git a/src/box/request.cc b/src/box/request.cc
index 4a476811f8e2bb1d3a821ab387ef6b3713cad969..3b662575d93db2f3d1f453ac8975c3c1a66e5241 100644
--- a/src/box/request.cc
+++ b/src/box/request.cc
@@ -113,7 +113,9 @@ execute_update(struct request *request, struct txn *txn)
 		return;
 
 	/* Update the tuple. */
-	struct tuple *new_tuple = tuple_update(old_tuple, *reqpos, reqend);
+	struct tuple *new_tuple = tuple_update(palloc_region_alloc,
+					       fiber->gc_pool,
+					       old_tuple, *reqpos, reqend);
 	try {
 		space_validate_tuple(sp, new_tuple);
 		txn_replace(txn, sp, old_tuple, new_tuple, DUP_INSERT);
diff --git a/src/box/tuple.cc b/src/box/tuple.cc
index 76d1e5dc79bfb5bda2e80dc9d10e36e61285665e..126b3ba1e50f694dac21614b9fde3245cfe87bda 100644
--- a/src/box/tuple.cc
+++ b/src/box/tuple.cc
@@ -195,20 +195,15 @@ tuple_print(struct tbuf *buf, const struct tuple *tuple)
 	tbuf_printf(buf, "}");
 }
 
-static void *
-palloc_region_alloc(void *ctx, size_t size)
-{
-	return palloc((struct palloc_pool *) ctx, size);
-}
-
 struct tuple *
-tuple_update(const struct tuple *old_tuple, const char *expr,
+tuple_update(void *(*region_alloc)(void *, size_t), void *alloc_ctx,
+	     const struct tuple *old_tuple, const char *expr,
 	     const char *expr_end)
 {
 	uint32_t new_size = 0;
 	uint32_t new_field_count = 0;
 	struct tuple_update *update =
-		tuple_update_prepare(palloc_region_alloc, fiber->gc_pool,
+		tuple_update_prepare(region_alloc, alloc_ctx,
 				     expr, expr_end, old_tuple->data,
 				     old_tuple->data + old_tuple->bsize,
 				     old_tuple->field_count, &new_size,
diff --git a/src/box/tuple.h b/src/box/tuple.h
index 401b21a26f67ca318e194091b456de5d474e2445..ad7bab91be969fe6658b36f6c673a6a6c64377b4 100644
--- a/src/box/tuple.h
+++ b/src/box/tuple.h
@@ -166,8 +166,9 @@ void
 tuple_print(struct tbuf *buf, const struct tuple *tuple);
 
 struct tuple *
-tuple_update(const struct tuple *old_tuple, const char *expr,
-             const char *expr_end);
+tuple_update(void *(*region_alloc)(void *, size_t), void *alloc_ctx,
+	     const struct tuple *old_tuple,
+	     const char *expr, const char *expr_end);
 
 /** Tuple length when adding to iov. */
 static inline size_t tuple_len(struct tuple *tuple)
diff --git a/src/lua/init.cc b/src/lua/init.cc
index f0699ce6e6e90f4d6d86ca6d5ce4733b8dcc611e..78e82997f961b20d5f59eb77d560f9326381acea 100644
--- a/src/lua/init.cc
+++ b/src/lua/init.cc
@@ -1560,3 +1560,10 @@ tarantool_lua_load_init_script(struct lua_State *L)
 	*/
 	tarantool_lua_sandbox(tarantool_L);
 }
+
+void *
+lua_region_alloc(void *ctx, size_t size)
+{
+	struct lua_State *L = (struct lua_State *) ctx;
+	return lua_newuserdata(L, size);
+}