diff --git a/mod/box/box.m b/mod/box/box.m
index 34afed24bea60af791da6bd9b44da2a85a12c85a..7fb633aa71747db0535edb274940327315652c56 100644
--- a/mod/box/box.m
+++ b/mod/box/box.m
@@ -84,9 +84,9 @@ box_process_rw(struct txn *txn, struct port *port,
 	ev_tstamp start = ev_now(), stop;
 
 	@try {
-		Request *request = [[Request build: op] init: data];
+		struct request *request = request_create(op, data);
 		stat_collect(stat_base, op, 1);
-		[request execute: txn :port];
+		request_execute(request, txn, port);
 		txn_commit(txn);
 	}
 	@catch (id e) {
diff --git a/mod/box/box_lua.h b/mod/box/box_lua.h
index 4fd259a77eda9bd55f2369c7f949d85dfae7be47..f0a109a2b757044cdf5d09578a52eb0038b3dcfd 100644
--- a/mod/box/box_lua.h
+++ b/mod/box/box_lua.h
@@ -35,9 +35,8 @@ struct lua_State;
  * Invoke a Lua stored procedure from the binary protocol
  * (implementation of 'CALL' command code).
  */
-@interface Call: Request
-- (void) execute: (struct txn *) txn :(struct port *) port;
-@end
+void
+box_lua_execute(struct request *request, struct txn *txn, struct port *port);
 
 /**
  * Create an instance of Lua interpreter in box.
diff --git a/mod/box/box_lua.m b/mod/box/box_lua.m
index 893829ddc3269b13dcf7a9c59231078ae4a54e17..b17a6dafe7492a948411d043733f700cf5d8ef2b 100644
--- a/mod/box/box_lua.m
+++ b/mod/box/box_lua.m
@@ -986,14 +986,15 @@ void box_lua_find(lua_State *L, const char *name, const char *name_end)
 	}
 }
 
-@implementation Call
 /**
  * Invoke a Lua stored procedure from the binary protocol
  * (implementation of 'CALL' command code).
  */
-- (void) execute: (struct txn *) txn : (struct port *)port
+void
+box_lua_execute(struct request *request, struct txn *txn, struct port *port)
 {
 	(void) txn;
+	struct tbuf *data = request->data;
 	lua_State *L = lua_newthread(root_L);
 	int coro_ref = luaL_ref(root_L, LUA_REGISTRYINDEX);
 	/* Request flags: not used. */
@@ -1025,7 +1026,6 @@ void box_lua_find(lua_State *L, const char *name, const char *name_end)
 		luaL_unref(root_L, LUA_REGISTRYINDEX, coro_ref);
 	}
 }
-@end
 
 void
 mod_lua_init(struct lua_State *L)
diff --git a/mod/box/request.h b/mod/box/request.h
index 815b3b80da48e6d0ef781d0f830bb577f2647ac1..ef739b580baaab93cd55c377802aac8c8dd74e09 100644
--- a/mod/box/request.h
+++ b/mod/box/request.h
@@ -100,14 +100,14 @@ request_is_select(u32 type)
 	return type == SELECT || type == CALL;
 }
 
-@interface Request: tnt_Object {
+struct request
+{
 	u32 type;
 	struct tbuf *data;
-}
-+ (Request *) alloc;
-+ (Request *) build: (u32) type_arg;
-- (id) init: (struct tbuf *) data_arg;
-- (void) execute: (struct txn *) txn :(struct port *) port;
-@end
+};
+
+struct request *request_create(u32 type, struct tbuf *data);
+
+void request_execute(struct request *request, struct txn *txn, struct port *port);
 
 #endif /* TARANTOOL_BOX_REQUEST_H_INCLUDED */
diff --git a/mod/box/request.m b/mod/box/request.m
index 80655d6d9a4c2c7c0fb581d2b71fb167851d9674..63555e1b6b78d4ab4dbd0e76c3775749ba62e909 100644
--- a/mod/box/request.m
+++ b/mod/box/request.m
@@ -77,14 +77,11 @@ port_send_tuple(u32 flags, struct port *port, struct tuple *tuple)
 	}
 }
 
-@interface Replace: Request
-- (void) execute: (struct txn *) txn :(struct port *) port;
-@end
-
-@implementation Replace
-- (void) execute: (struct txn *) txn :(struct port *) port
+static void
+execute_replace(struct request *request, struct txn *txn, struct port *port)
 {
-	txn_add_redo(txn, type, data);
+	struct tbuf *data = request->data;
+	txn_add_redo(txn, request->type, data);
 	struct space *sp = read_space(data);
 	u32 flags = read_u32(data) & BOX_ALLOWED_REQUEST_FLAGS;
 	size_t field_count = read_u32(data);
@@ -117,7 +114,6 @@ port_send_tuple(u32 flags, struct port *port, struct tuple *tuple)
 	if (flags & BOX_RETURN_TUPLE)
 		port_add_tuple(port, txn->new_tuple);
 }
-@end
 
 /** {{{ UPDATE request implementation.
  * UPDATE request is represented by a sequence of operations, each
@@ -181,10 +177,6 @@ port_send_tuple(u32 flags, struct port *port, struct tuple *tuple)
  * to store intermediate operation results.
  */
 
-@interface Update: Request
-- (void) execute: (struct txn *) txn :(struct port *) port;
-@end
-
 /** Argument of SET operation. */
 struct op_set_arg {
 	u32 length;
@@ -682,10 +674,7 @@ update_read_ops(struct tbuf *data, u32 op_cnt)
 		tnt_raise(IllegalParams, :"too many operations for update");
 	if (op_cnt == 0)
 		tnt_raise(IllegalParams, :"no operations for update");
-	/*
-	 * Read update operations. Allocate an extra dummy op to
-	 * optionally "apply" to the first field.
-	 */
+	/* Read update operations.  */
 	struct update_op *ops = palloc(fiber->gc_pool, op_cnt *
 				       sizeof(struct update_op));
 	struct update_op *op = ops, *ops_end = ops + op_cnt;
@@ -707,11 +696,11 @@ update_read_ops(struct tbuf *data, u32 op_cnt)
 	return ops;
 }
 
-
-@implementation Update
-- (void) execute: (struct txn *) txn :(struct port *) port
+static void
+execute_update(struct request *request, struct txn *txn, struct port *port)
 {
-	txn_add_redo(txn, type, data);
+	struct tbuf *data = request->data;
+	txn_add_redo(txn, request->type, data);
 	struct space *sp = read_space(data);
 	u32 flags = read_u32(data) & BOX_ALLOWED_REQUEST_FLAGS;
 
@@ -742,17 +731,13 @@ update_read_ops(struct tbuf *data, u32 op_cnt)
 	txn_add_undo(txn, sp, old_tuple, txn->new_tuple);
 	port_send_tuple(flags, port, txn->new_tuple);
 }
-@end
 
 /** }}} */
 
-@interface Select: Request
-- (void) execute: (struct txn *) txn :(struct port *) port;
-@end
-
-@implementation Select
-- (void) execute: (struct txn *) txn :(struct port *) port
+static void
+execute_select(struct request *request, struct txn *txn, struct port *port)
 {
+	struct tbuf *data = request->data;
 	(void) txn; /* Not used. */
 	struct space *sp = read_space(data);
 	u32 index_no = read_u32(data);
@@ -801,15 +786,12 @@ update_read_ops(struct tbuf *data, u32 op_cnt)
 	if (data->size != 0)
 		tnt_raise(IllegalParams, :"can't unpack request");
 }
-@end
 
-@interface Delete: Request
-- (void) execute: (struct txn *) txn :(struct port *) port;
-@end
-
-@implementation Delete
-- (void) execute: (struct txn *) txn :(struct port *) port
+static void
+execute_delete(struct request *request, struct txn *txn, struct port *port)
 {
+	struct tbuf *data = request->data;
+	u32 type = request->type;
 	txn_add_redo(txn, type, data);
 	u32 flags = 0;
 	struct space *sp = read_space(data);
@@ -826,59 +808,57 @@ update_read_ops(struct tbuf *data, u32 op_cnt)
 
 	port_send_tuple(flags, port, old_tuple);
 }
-@end
 
-@implementation Request
-+ (Request *) alloc
+/** To collects stats, we need a valid request type.
+ * We must collect stats before execute.
+ * Check request type here for now.
+ */
+static void
+request_check_type(u32 type)
 {
-	size_t sz = class_getInstanceSize(self);
-	id new = palloca(fiber->gc_pool, sz, sizeof(void *));
-	memset(new, 0, sz);
-	object_setClass(new, self);
-	return new;
+	if (type != REPLACE && type != SELECT &&
+	    type != UPDATE && type != DELETE_1_3 &&
+	    type != DELETE && type != CALL) {
+
+		say_error("Unsupported request = %" PRIi32 "", type);
+		tnt_raise(IllegalParams, :"unsupported command code, "
+			  "check the error log");
+	}
 }
 
-+ (Request *) build: (u32) type_arg
+struct request *
+request_create(u32 type, struct tbuf *data)
 {
-	Request *new = nil;
-	switch (type_arg) {
+	request_check_type(type);
+	struct request *request = palloc(fiber->gc_pool, sizeof(struct request));
+	request->type = type;
+	request->data = data;
+	return request;
+}
+
+void
+request_execute(struct request *request, struct txn *txn, struct port *port)
+{
+	switch (request->type) {
 	case REPLACE:
-		new = [Replace alloc]; break;
+		execute_replace(request, txn, port);
+		break;
 	case SELECT:
-		new = [Select alloc]; break;
+		execute_select(request, txn, port);
+		break;
 	case UPDATE:
-		new = [Update alloc]; break;
+		execute_update(request, txn, port);
+		break;
 	case DELETE_1_3:
 	case DELETE:
-		new = [Delete alloc]; break;
+		execute_delete(request, txn, port);
+		break;
 	case CALL:
-		new = [Call alloc]; break;
+		box_lua_execute(request, txn, port);
+		break;
 	default:
-		say_error("Unsupported request = %" PRIi32 "", type_arg);
-		tnt_raise(IllegalParams, :"unsupported command code, "
-			  "check the error log");
+		assert(false);
+		request_check_type(request->type);
 		break;
 	}
-	new->type = type_arg;
-	return new;
 }
-
-- (id) init: (struct tbuf *) data_arg
-{
-	assert(type);
-	self = [super init];
-	if (self == nil)
-		return self;
-
-	data = data_arg;
-	return self;
-}
-
-- (void) execute: (struct txn *) txn :(struct port *) port
-{
-	(void) txn;
-	(void) port;
-	[self subclassResponsibility: _cmd];
-}
-@end
-