diff --git a/mod/box/memcached.m b/mod/box/memcached.m
index 71a5ee5c5f83a343ca5dcb06347b128635b9ff22..2e1ac538bb66a57d7b0dc7854b353dd5e8c4488a 100644
--- a/mod/box/memcached.m
+++ b/mod/box/memcached.m
@@ -378,13 +378,13 @@ memcached_loop(struct coio *coio)
 
 void memcached_handler(va_list ap)
 {
-	struct coio *coio = va_arg(ap, struct coio *);
+	struct coio coio = va_arg(ap, struct coio);
 	stats.total_connections++;
 	stats.curr_connections++;
 
 	@try {
-		memcached_loop(coio);
-		iov_flush(coio);
+		memcached_loop(&coio);
+		iov_flush(&coio);
 	} @catch (FiberCancelException *e) {
 		@throw;
 	} @catch (tnt_Exception *e) {
@@ -393,8 +393,7 @@ void memcached_handler(va_list ap)
 		iov_reset();
 		fiber_sleep(0.01);
 		stats.curr_connections--;
-		coio_close(coio);
-		free(coio);
+		coio_close(&coio);
 	}
 }
 
diff --git a/src/admin.m b/src/admin.m
index 52363636826a6d4fb297d56a0401327c67cbd966..cfc9d66955ca594aa9f7289f31af616c07ff3b1d 100644
--- a/src/admin.m
+++ b/src/admin.m
@@ -1910,19 +1910,18 @@ case 134:
 static void
 admin_handler(va_list ap)
 {
-	struct coio *coio = va_arg(ap, struct coio *);
+	struct coio coio = va_arg(ap, struct coio);
 	lua_State *L = lua_newthread(tarantool_L);
 	int coro_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX);
 	@try {
 		for (;;) {
-			if (admin_dispatch(coio, L) < 0)
+			if (admin_dispatch(&coio, L) < 0)
 				return;
 			fiber_gc();
 		}
 	} @finally {
 		luaL_unref(tarantool_L, LUA_REGISTRYINDEX, coro_ref);
-		coio_close(coio);
-		free(coio);
+		coio_close(&coio);
 	}
 }
 
diff --git a/src/admin.rl b/src/admin.rl
index 66847749effa6a36b40e7e9585b4a5353206fc2c..f1deecde6a86e19aa7ec59e9bc230600cdcd5ad9 100644
--- a/src/admin.rl
+++ b/src/admin.rl
@@ -339,19 +339,18 @@ admin_dispatch(struct coio *coio, lua_State *L)
 static void
 admin_handler(va_list ap)
 {
-	struct coio *coio = va_arg(ap, struct coio *);
+	struct coio coio = va_arg(ap, struct coio);
 	lua_State *L = lua_newthread(tarantool_L);
 	int coro_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX);
 	@try {
 		for (;;) {
-			if (admin_dispatch(coio, L) < 0)
+			if (admin_dispatch(&coio, L) < 0)
 				return;
 			fiber_gc();
 		}
 	} @finally {
 		luaL_unref(tarantool_L, LUA_REGISTRYINDEX, coro_ref);
-		coio_close(coio);
-		free(coio);
+		coio_close(&coio);
 	}
 }
 
diff --git a/src/coio.m b/src/coio.m
index 8e1ee0d4d217503acdba6acd8fc95e4d86ebce8a..e4cb895f583e6c39f7ea93cb513f3bd82b8cd219 100644
--- a/src/coio.m
+++ b/src/coio.m
@@ -254,12 +254,9 @@ coio_service_on_accept(struct evio_service *evio_service,
 		       int fd, struct sockaddr_in *addr)
 {
 	struct coio_service *service = evio_service->on_accept_param;
-	struct coio *coio = malloc(sizeof(struct coio));
+	struct coio coio;
 
-	if (coio == NULL)
-		goto error;
-
-	coio_init(coio, fd);
+	coio_init(&coio, fd);
 
 	/* Set connection name. */
 	char name[SERVICE_NAME_MAXLEN];
@@ -268,15 +265,13 @@ coio_service_on_accept(struct evio_service *evio_service,
 
 	/* Create the worker fiber. */
 	struct fiber *f = fiber_create(name, service->handler);
-	if (f == NULL) {
-		free(coio);
+	if (f == NULL)
 		goto error;
-	}
 	/*
 	 * The coio is passed on to the created fiber, reset the
 	 * libev callback param to point at it.
 	 */
-	coio->ev.data = f;
+	coio.ev.data = f;
 	/*
 	 * Start the created fiber. It becomes the coio object owner
 	 * and will have to close it and free before termination.
diff --git a/src/iproto.m b/src/iproto.m
index 4495dd8e040c071f70bdde53d2e6ec96cac95be1..cb6ea44cfdbbacc4d7d01d0f02cef5f11debaaf8 100644
--- a/src/iproto.m
+++ b/src/iproto.m
@@ -62,13 +62,13 @@ iproto_flush(struct coio *coio, ssize_t to_read)
 void
 iproto_interact(va_list ap)
 {
-	struct coio *coio = va_arg(ap, struct coio *);
+	struct coio coio = va_arg(ap, struct coio);
 	iproto_callback callback = va_arg(ap, iproto_callback);
 	struct tbuf *in = &fiber->rbuf;
 	ssize_t to_read = sizeof(struct iproto_header);
 	@try {
 		for (;;) {
-			if (to_read > 0 && coio_bread(coio, in, to_read) <= 0)
+			if (to_read > 0 && coio_bread(&coio, in, to_read) <= 0)
 				break;
 
 			/* validating iproto package header */
@@ -78,20 +78,19 @@ iproto_interact(va_list ap)
 				+ iproto(in)->len;
 			to_read = request_len - in->size;
 
-			iproto_flush(coio, to_read);
+			iproto_flush(&coio, to_read);
 
-			if (to_read > 0 && coio_bread(coio, in, to_read) <= 0)
+			if (to_read > 0 && coio_bread(&coio, in, to_read) <= 0)
 				break;
 
 			struct tbuf *request = tbuf_split(in, request_len);
 			iproto_reply(callback, request);
 
 			to_read = sizeof(struct iproto_header) - in->size;
-			iproto_flush(coio, to_read);
+			iproto_flush(&coio, to_read);
 		}
 	} @finally {
-		coio_close(coio);
-		free(coio);
+		coio_close(&coio);
 	}
 }