diff --git a/src/lua/bsdsocket.lua b/src/lua/bsdsocket.lua
index 6d7c5edaecab38bf80ccba4ea6214a29a1c88161..cb0b11e51a799bf7533193d9d8bf5dffe121eb51 100644
--- a/src/lua/bsdsocket.lua
+++ b/src/lua/bsdsocket.lua
@@ -582,7 +582,7 @@ local errno_is_fatal = {
 }
 
 local function check_limit(self, limit)
-    if self.rbuf.size >= limit then
+    if self.rbuf:size() >= limit then
         return limit
     end
     return nil
@@ -593,13 +593,13 @@ local function check_delimiter(self, limit, eols)
         return 0
     end
     local rbuf = self.rbuf
-    if rbuf.size == 0 then
+    if rbuf:size() == 0 then
         return nil
     end
 
     local shortest
     for i, eol in ipairs(eols) do
-        local data = ffi.C.memmem(rbuf.rpos, rbuf.size, eol, #eol)
+        local data = ffi.C.memmem(rbuf.rpos, rbuf:size(), eol, #eol)
         if data ~= nil then
             local len = ffi.cast('char *', data) - rbuf.rpos + #eol
             if shortest == nil or shortest > len then
@@ -609,7 +609,7 @@ local function check_delimiter(self, limit, eols)
     end
     if shortest ~= nil and shortest <= limit then
         return shortest
-    elseif limit <= rbuf.size then
+    elseif limit <= rbuf:size() then
         return limit
     end
     return nil
@@ -636,14 +636,14 @@ local function read(self, limit, timeout, check, ...)
     while timeout > 0 do
         local started = fiber.time()
 
-        assert(rbuf.size < limit)
-        local to_read = math.min(limit - rbuf.size, buffer.READAHEAD)
+        assert(rbuf:size() < limit)
+        local to_read = math.min(limit - rbuf:size(), buffer.READAHEAD)
         local data = rbuf:reserve(to_read)
-        assert(rbuf.unused >= to_read)
-        local res = sysread(self, data, rbuf.unused)
+        assert(rbuf:unused() >= to_read)
+        local res = sysread(self, data, rbuf:unused())
         if res == 0 then -- eof
             self._errno = nil
-            local len = rbuf.size
+            local len = rbuf:size()
             local data = ffi.string(rbuf.rpos, len)
             rbuf.rpos = rbuf.rpos + len
             return data
diff --git a/src/lua/buffer.lua b/src/lua/buffer.lua
index 6823b0a98a11e0b4a4c391c9a4000ed7cd0c29c1..0f9a3cdf476559c5ca52f8a4df411e66282ed214 100644
--- a/src/lua/buffer.lua
+++ b/src/lua/buffer.lua
@@ -127,18 +127,8 @@ local function ibuf_read(buf, size)
     return rpos
 end
 
-local ibuf_properties = {
-    size = ibuf_used;
-    capacity = ibuf_capacity;
-    pos = ibuf_pos;
-    unused = ibuf_unused;
-}
-
 local function ibuf_serialize(buf)
     local properties = { rpos = buf.rpos, wpos = buf.wpos }
-    for key, getter in pairs(ibuf_properties) do
-        properties[key] = getter(buf)
-    end
     return { ibuf = properties }
 end
 
@@ -152,26 +142,19 @@ local ibuf_methods = {
     checksize = ibuf_checksize;
     read = ibuf_read;
     __serialize = ibuf_serialize;
-}
 
-local function ibuf_index(buf, key)
-    local property = ibuf_properties[key]
-    if property ~= nil then
-        return property(buf)
-    end
-    local method = ibuf_methods[key]
-    if method ~= nil then
-        return method
-    end
-    return nil
-end
+    size = ibuf_used;
+    capacity = ibuf_capacity;
+    pos = ibuf_pos;
+    unused = ibuf_unused;
+}
 
 local function ibuf_tostring(ibuf)
     return '<ibuf>'
 end
 local ibuf_mt = {
     __gc = ibuf_recycle;
-    __index = ibuf_index;
+    __index = ibuf_methods;
     __tostring = ibuf_tostring;
 };
 
diff --git a/src/lua/msgpackffi.lua b/src/lua/msgpackffi.lua
index 7fd585ca630c714dfb7df3fd1006f7dd7a428b7a..b6168ed57b7f9ee213cf8ddeb5048bbe119282d5 100644
--- a/src/lua/msgpackffi.lua
+++ b/src/lua/msgpackffi.lua
@@ -227,7 +227,7 @@ local function encode(obj)
     local tmpbuf = buffer.IBUF_SHARED
     tmpbuf:reset()
     encode_r(tmpbuf, obj, 0)
-    local r = ffi.string(tmpbuf.rpos, tmpbuf.size)
+    local r = ffi.string(tmpbuf.rpos, tmpbuf:size())
     tmpbuf:recycle()
     return r
 end
diff --git a/src/lua/net_box.lua b/src/lua/net_box.lua
index 038c251418d794a614ed894172a9abb1f270b35b..5b5255796da8a20cf7413ed0145e6e9f400d19e2 100644
--- a/src/lua/net_box.lua
+++ b/src/lua/net_box.lua
@@ -599,7 +599,7 @@ local remote_methods = {
 
     _check_console_response = function(self)
         local docend = "\n...\n"
-        local resp = ffi.string(self.rbuf.rpos, self.rbuf.size)
+        local resp = ffi.string(self.rbuf.rpos, self.rbuf:size())
 
         if #resp < #docend or
                 string.sub(resp, #resp + 1 - #docend) ~= docend then
@@ -619,10 +619,21 @@ local remote_methods = {
         return 0
     end,
 
+    _wakeup_client = function(self, hdr, body)
+        local sync = hdr[SYNC]
+
+        if self.ch.sync[sync] ~= nil then
+            self.ch.sync[sync]:put({ hdr = hdr, body = body })
+            self.ch.sync[sync] = nil
+        else
+            log.warn("Unexpected response %s", tostring(sync))
+        end
+    end,
+
     _check_binary_response = function(self)
         while true do
-            if self.rbuf.size < 5 then
-                return 0
+            if self.rbuf.rpos + 5 > self.rbuf.wpos then
+                return 5 - (self.wpos - self.rpos)
             end
 
             local rpos, len = msgpack.ibuf_decode(self.rbuf.rpos)
@@ -639,16 +650,9 @@ local remote_methods = {
             setmetatable(body, mapping_mt)
 
             self.rbuf.rpos = rpos
-            local sync = hdr[SYNC]
-
-            if self.ch.sync[sync] ~= nil then
-                self.ch.sync[sync]:put({ hdr = hdr, body = body })
-                self.ch.sync[sync] = nil
-            else
-                log.warn("Unexpected response %s", tostring(sync))
-            end
+            self:_wakeup_client(hdr, body)
 
-           if self.rbuf.size == 0 then
+           if self.rbuf:size() == 0 then
                 return 0
             end
         end
@@ -899,7 +903,7 @@ local remote_methods = {
         self.rbuf = buffer.ibuf(buffer.READAHEAD)
         while self:_wait_state(self._r_states) ~= 'closed' do
             if self.s:readable() then
-                local len = self.s:sysread(self.rbuf.wpos, self.rbuf.unused)
+                local len = self.s:sysread(self.rbuf.wpos, self.rbuf:unused())
                 if len ~= nil then
                     if len == 0 then
                         self:_fatal('Remote host closed connection')