diff --git a/src/box/box.cc b/src/box/box.cc
index 6d7f42dbf1dc001df1650b410cbe40c4e5b5bcff..c0558a12d0708424593c907d26bee137a6df77a7 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -123,7 +123,8 @@ recover_row(void *param __attribute__((unused)), const struct log_row *row)
 		const char *end = data + row->len;
 		uint16_t op = pick_u16(&data, end);
 		struct request request;
-		request_create(&request, op, data, end - data);
+		request_create(&request, op);
+		request_decode(&request, data, end - data);
 		process_rw(&null_port, &request);
 	} catch (const Exception& e) {
 		e.log();
diff --git a/src/box/lua/call.cc b/src/box/lua/call.cc
index 99eeae31cc983d2390abf136a8d76a59d810e525..e6176f0f27caa7d5a3ddf299418594a390c18a87 100644
--- a/src/box/lua/call.cc
+++ b/src/box/lua/call.cc
@@ -193,7 +193,8 @@ lbox_process(lua_State *L)
 	struct port *port_lua = port_lua_create(L);
 	try {
 		struct request request;
-		request_create(&request, op, req, sz);
+		request_create(&request, op);
+		request_decode(&request, req, sz);
 		box_process(port_lua, &request);
 
 		/*
@@ -222,21 +223,19 @@ lbox_select(lua_State *L)
 	luamp_encode(L, buf, 3);
 
 	struct request request;
-	request_create(&request, IPROTO_SELECT, NULL, 0);
+	request_create(&request, IPROTO_SELECT);
 	request.space_id = lua_tointeger(L, 1);
 	request.index_id = lua_tointeger(L, 2);
 	request.limit = 4294967295;
 	request.key = buf->data;
 	request.key_end = buf->data + buf->size;
 
-	struct port *port_lua = port_lua_create(L);
-	box_process(port_lua, &request);
-
+	box_process(port_lua_create(L), &request);
 	return lua_gettop(L) - 3;
 }
 
 static int
-lbox_insert_replace(lua_State *L, enum iproto_request_type type)
+lbox_insert_or_replace(lua_State *L, enum iproto_request_type type)
 {
 	assert(type == IPROTO_INSERT || type == IPROTO_REPLACE);
 	if (lua_gettop(L) < 2 || !lua_isnumber(L, 1))
@@ -249,26 +248,25 @@ lbox_insert_replace(lua_State *L, enum iproto_request_type type)
 	luamp_encode(L, buf, 2);
 
 	struct request request;
-	request_create(&request, type, NULL, 0);
+	request_create(&request, type);
 	request.space_id = lua_tointeger(L, 1);
 	request.tuple = buf->data;
 	request.tuple_end = buf->data + buf->size;
 
-	struct port *port_lua = port_lua_create(L);
-	box_process(port_lua, &request);
+	box_process(port_lua_create(L), &request);
 	return lua_gettop(L) - 2;
 }
 
 static int
 lbox_insert(lua_State *L)
 {
-	return lbox_insert_replace(L, IPROTO_INSERT);
+	return lbox_insert_or_replace(L, IPROTO_INSERT);
 }
 
 static int
 lbox_replace(lua_State *L)
 {
-	return lbox_insert_replace(L, IPROTO_REPLACE);
+	return lbox_insert_or_replace(L, IPROTO_REPLACE);
 }
 
 static int
@@ -287,7 +285,7 @@ lbox_update(lua_State *L)
 	luamp_encode(L, buf, 3);
 
 	struct request request;
-	request_create(&request, IPROTO_UPDATE, NULL, 0);
+	request_create(&request, IPROTO_UPDATE);
 	request.space_id = lua_tointeger(L, 1);
 	request.index_id = lua_tointeger(L, 2);
 	request.tuple = buf->data;
@@ -295,8 +293,7 @@ lbox_update(lua_State *L)
 	request.key = buf->data + tuple_len;
 	request.key_end = buf->data + buf->size;
 
-	struct port *port_lua = port_lua_create(L);
-	box_process(port_lua, &request);
+	box_process(port_lua_create(L), &request);
 	return lua_gettop(L) - 3;
 }
 
@@ -314,14 +311,13 @@ lbox_delete(lua_State *L)
 	luamp_encode(L, buf, 3);
 
 	struct request request;
-	request_create(&request, IPROTO_DELETE, NULL, 0);
+	request_create(&request, IPROTO_DELETE);
 	request.space_id = lua_tointeger(L, 1);
 	request.index_id = lua_tointeger(L, 2);
 	request.key = buf->data;
 	request.key_end = buf->data + buf->size;
 
-	struct port *port_lua = port_lua_create(L);
-	box_process(port_lua, &request);
+	box_process(port_lua_create(L), &request);
 	return lua_gettop(L) - 3;
 }
 
diff --git a/src/box/request.cc b/src/box/request.cc
index 0e11d36617cccc14643de538e3977b20595a6ad3..478d42279f69480d21acb7f9774c6337fb3acd1c 100644
--- a/src/box/request.cc
+++ b/src/box/request.cc
@@ -275,8 +275,7 @@ request_check_type(uint32_t type)
 }
 
 void
-request_create(struct request *request, uint32_t type,
-	       const char *data, uint32_t len)
+request_create(struct request *request, uint32_t type)
 {
 	request_check_type(type);
 	static const request_execute_f execute_map[] = {
@@ -289,13 +288,14 @@ request_create(struct request *request, uint32_t type,
 	};
 	memset(request, 0, sizeof(*request));
 	request->type = type;
-	request->data = data;
-	request->len = len;
 	request->execute = execute_map[type];
 	request->fill = fill_map[type];
-	if (data == NULL)
-		return;
+}
 
+void
+request_decode(struct request *request, const char *data, uint32_t len)
+{
+	assert(request->type != 0);
 	const char *end = data + len;
 
 	if (mp_typeof(*data) != MP_MAP || ! mp_check_map(data, end)) {
diff --git a/src/box/request.h b/src/box/request.h
index ddef8cb6814312829b51124cbda2a79142af4692..d168c9dc189e3106572299b7019aa416e3f2366a 100644
--- a/src/box/request.h
+++ b/src/box/request.h
@@ -61,7 +61,9 @@ struct request
 };
 
 void
-request_create(struct request *request, uint32_t type, const char *data,
-	       uint32_t len);
+request_create(struct request *request, uint32_t type);
+
+void
+request_decode(struct request *request, const char *data, uint32_t len);
 
 #endif /* TARANTOOL_BOX_REQUEST_H_INCLUDED */
diff --git a/src/box/txn.cc b/src/box/txn.cc
index 53d12203aab2eafdba99816bbb00c752fa46730e..941e3468c75653c1042156e315b116f3c312aadd 100644
--- a/src/box/txn.cc
+++ b/src/box/txn.cc
@@ -83,31 +83,34 @@ txn_commit(struct txn *txn)
 {
 	if ((txn->old_tuple || txn->new_tuple) &&
 	    !space_is_temporary(txn->space)) {
+		struct request *request = txn->request;
 		int64_t lsn = next_lsn(recovery_state);
 
-		if (txn->request->data == NULL &&
-		    recovery_state->wal_mode != WAL_NONE) {
-			/* Generate binary body for Lua requests */
-			assert(txn->request->fill != NULL);
-			txn->request->fill(txn->request);
-		}
+		int res = 0;
+		if (recovery_state->wal_mode != WAL_NONE) {
+			if (request->data == NULL) {
+				/* Generate binary body for Lua requests */
+				assert(request->fill != NULL);
+				request->fill(request);
+			}
 
-		ev_tstamp start = ev_now(), stop;
-		int res = wal_write(recovery_state, lsn, fiber()->cookie,
-				    txn->request->type, txn->request->data,
-				    txn->request->len);
-		stop = ev_now();
+			ev_tstamp start = ev_now(), stop;
+			res = wal_write(recovery_state, lsn, fiber()->cookie,
+					request->type, request->data,
+					request->len);
+			stop = ev_now();
 
-		if (stop - start > cfg.too_long_threshold) {
-			say_warn("too long %s: %.3f sec",
-				 iproto_request_name(txn->request->type), stop - start);
+			if (stop - start > cfg.too_long_threshold) {
+				say_warn("too long %s: %.3f sec",
+					 iproto_request_name(request->type),
+					 stop - start);
+			}
 		}
 
 		confirm_lsn(recovery_state, lsn, res == 0);
 
 		if (res)
 			tnt_raise(LoggedError, ER_WAL_IO);
-
 	}
 	trigger_run(&txn->on_commit, txn); /* must not throw. */
 }
diff --git a/src/iproto.cc b/src/iproto.cc
index 425ef3985f55ffca6ec298cf9444c55b6b0bc7da..57ee0ca11fc5111ab725fcf27f002bbe2a3d2ae7 100644
--- a/src/iproto.cc
+++ b/src/iproto.cc
@@ -684,7 +684,8 @@ iproto_process_request(struct iproto_request *ireq)
 	iproto_port_init(&port, out, ireq->sync);
 	try {
 		struct request request;
-		request_create(&request, ireq->code, ireq->body, ireq->len);
+		request_create(&request, ireq->code);
+		request_decode(&request, ireq->body, ireq->len);
 		(*con->handler)((struct port *) &port, &request);
 	} catch (const ClientError &e) {
 		if (port.found)
diff --git a/src/recovery.cc b/src/recovery.cc
index a9e33bd5041d63c3443f08599f248def97411bfd..f435f6e6a1b08851c9ba3066e507859475d0fd39 100644
--- a/src/recovery.cc
+++ b/src/recovery.cc
@@ -1188,12 +1188,10 @@ int
 wal_write(struct recovery_state *r, int64_t lsn, uint64_t cookie,
 	  uint16_t op, const char *row, uint32_t row_len)
 {
+	assert(r->wal_mode != WAL_NONE);
 	say_debug("wal_write lsn=%" PRIi64, lsn);
 	ERROR_INJECT_RETURN(ERRINJ_WAL_IO);
 
-	if (r->wal_mode == WAL_NONE)
-		return 0;
-
 	struct wal_writer *writer = r->writer;
 
 	struct wal_write_request *req = (struct wal_write_request *)