diff --git a/src/lua/msgpackffi.lua b/src/lua/msgpackffi.lua
index 5b758c447e40595329deaf50f541c1a031a92cf6..d63d2905126731e6067414ec986a79535bb703aa 100644
--- a/src/lua/msgpackffi.lua
+++ b/src/lua/msgpackffi.lua
@@ -289,6 +289,9 @@ on_encode(ffi.typeof('double'), encode_double)
 -- Decoder
 --------------------------------------------------------------------------------
 
+local array_mt = { __serialize = 'seq' }
+local map_mt = { __serialize = 'map' }
+
 local decode_r
 
 local function decode_u8(data)
@@ -367,7 +370,7 @@ local function decode_array(data, size)
     for i=1,size,1 do
         table.insert(arr, decode_r(data))
     end
-    return arr
+    return setmetatable(arr, array_mt)
 end
 
 local function decode_map(data, size)
@@ -379,7 +382,7 @@ local function decode_map(data, size)
         local val = decode_r(data);
         map[key] = val
     end
-    return map
+    return setmetatable(map, map_mt)
 end
 
 local decoder_hint = {
diff --git a/test/app/msgpackffi.result b/test/app/msgpackffi.result
index 940ce93039e44168f257c213c43675cf33580fc8..8432aab5d79be25eba8cce3899bbe2c893080df2 100644
--- a/test/app/msgpackffi.result
+++ b/test/app/msgpackffi.result
@@ -157,8 +157,10 @@ ok - table
     # offsets: end
 ok - offsets
     # other
-    1..1
+    1..3
     ok - gh-633 double decode
+    ok - array save __serialize
+    ok - map save __serialize
     # other: end
 ok - other
 # msgpackffi: end
diff --git a/test/app/msgpackffi.test.lua b/test/app/msgpackffi.test.lua
index e70bdf8ba8cdb7316db1dc81478d3187acb61751..60c01b06ad3606bc709ef311cf256f6a29bc0fe4 100755
--- a/test/app/msgpackffi.test.lua
+++ b/test/app/msgpackffi.test.lua
@@ -36,12 +36,20 @@ local function test_offsets(test, s)
 end
 
 local function test_other(test, s)
-    test:plan(1)
+    test:plan(3)
     local buf = string.char(0x93, 0x6e, 0xcb, 0x42, 0x2b, 0xed, 0x30, 0x47,
         0x6f, 0xff, 0xff, 0xac, 0x77, 0x6b, 0x61, 0x71, 0x66, 0x7a, 0x73,
         0x7a, 0x75, 0x71, 0x71, 0x78)
-	local num = s.decode(buf)[2]
+    local num = s.decode(buf)[2]
     test:ok(num < 59971740600 and num > 59971740599, "gh-633 double decode")
+
+    -- gh-596: msgpack and msgpackffi have different behaviour
+    local arr = {1, 2, 3}
+    local map = {k1 = 'v1', k2 = 'v2', k3 = 'v3'}
+    test:is(getmetatable(s.decode(s.encode(arr))).__serialize, "seq",
+        "array save __serialize")
+    test:is(getmetatable(s.decode(s.encode(map))).__serialize, "map",
+        "map save __serialize")
 end
 
 tap.test("msgpackffi", function(test)
diff --git a/test/box/tuple.result b/test/box/tuple.result
index 08db8a8078a3e7da70afa3ab1b159944d26297a0..39186ccb62c8062320c50f1e5583510c7ab95dc4 100644
--- a/test/box/tuple.result
+++ b/test/box/tuple.result
@@ -205,11 +205,11 @@ box.tuple.new{1, 2, 3, 4, 5}
 ...
 box.tuple.new({'a', 'b'}, {'c', 'd'}, {'e', 'f'})
 ---
-- [['a', b], ['c', 'd'], ['e', 'f']]
+- [['a', 'b'], ['c', 'd'], ['e', 'f']]
 ...
 box.tuple.new{{'a', 'b'}, {'c', 'd'}, {'e', 'f'}}
 ---
-- [['a', b], ['c', 'd'], ['e', 'f']]
+- [['a', 'b'], ['c', 'd'], ['e', 'f']]
 ...
 box.tuple.new({1, 2}, 'x', 'y', 'z', {c = 3, d = 4}, {e = 5, f = 6})
 ---
@@ -287,17 +287,7 @@ t=space:get{777}:totable()
 ...
 t[2], t[3], t[4], t[5]
 ---
-- - a
-  - b
-  - c
-  - - d
-    - e
-    - - 0
-      - 777
-      - '0'
-      - '1'
-      - '2'
-      - '3'
+- ['a', 'b', 'c', ['d', 'e', [0, 777, '0', '1', '2', '3']]]
 - null
 - null
 - null