diff --git a/src/box/lua/xlog.c b/src/box/lua/xlog.c
index 805ea1ba1fa6f64812aaeddb57c513cfc601bf90..e92db3919dbef7d0063ef1640750f497f392294a 100644
--- a/src/box/lua/xlog.c
+++ b/src/box/lua/xlog.c
@@ -202,6 +202,11 @@ lbox_xlog_parser_iterate(struct lua_State *L)
 		lua_pushnumber(L, row.type); /* unknown key */
 	}
 	lua_settable(L, -3); /* type */
+	if (row.sync != 0) {
+		lbox_xlog_pushkey(L, iproto_key_name(IPROTO_SYNC));
+		lua_pushinteger(L, row.sync);
+		lua_settable(L, -3); /* sync */
+	}
 	if (row.lsn != 0) {
 		lbox_xlog_pushkey(L, iproto_key_name(IPROTO_LSN));
 		lua_pushinteger(L, row.lsn);
diff --git a/src/box/xlog.cc b/src/box/xlog.cc
index 8d625e6c807ca6dd1325d8ced1a5df516f7fa4f0..b3088300ed8e7b18604ee3051727e57a46f67190 100644
--- a/src/box/xlog.cc
+++ b/src/box/xlog.cc
@@ -1161,7 +1161,7 @@ xlog_tx_write(struct xlog *log)
  * @retval >=0 the number of bytes written to buffer.
  */
 ssize_t
-xlog_write_row(struct xlog *log, struct xrow_header *packet)
+xlog_write_row(struct xlog *log, const struct xrow_header *packet)
 {
 	/*
 	 * Automatically reserve space for a fixheader when adding
@@ -1181,9 +1181,7 @@ xlog_write_row(struct xlog *log, struct xrow_header *packet)
 	/** encode row into iovec */
 	struct iovec iov[XROW_IOVMAX];
 	/** don't write sync to the disk */
-	uint64_t sync = packet->sync;
-	int iovcnt = xrow_header_encode(packet, iov, 0);
-	packet->sync = sync;
+	int iovcnt = xrow_header_encode(packet, 0, iov, 0);
 	if (iovcnt < 0) {
 		obuf_rollback_to_svp(&log->obuf, &svp);
 		return -1;
diff --git a/src/box/xlog.h b/src/box/xlog.h
index 4a6f062da24b7dfc80117ae05dc96ff84543a5c1..253abfadaff0d8cfe940a4854277d0c4fec73454 100644
--- a/src/box/xlog.h
+++ b/src/box/xlog.h
@@ -403,7 +403,7 @@ xlog_rename(struct xlog *l);
  * @retval -1 for error
  */
 ssize_t
-xlog_write_row(struct xlog *log, struct xrow_header *packet);
+xlog_write_row(struct xlog *log, const struct xrow_header *packet);
 
 /**
  * Prevent xlog row buffer offloading, should be use
diff --git a/src/box/xrow.c b/src/box/xrow.c
index 055705927864cc94329287ef720392f02485dba0..26736fc74a4f90e2f36acc26960d5a22895516da 100644
--- a/src/box/xrow.c
+++ b/src/box/xrow.c
@@ -128,8 +128,8 @@ xrow_decode_uuid(const char **pos, struct tt_uuid *out)
 }
 
 int
-xrow_header_encode(const struct xrow_header *header, struct iovec *out,
-		   size_t fixheader_len)
+xrow_header_encode(const struct xrow_header *header, uint64_t sync,
+		   struct iovec *out, size_t fixheader_len)
 {
 	/* allocate memory for sign + header */
 	out->iov_base = region_alloc(&fiber()->gc, XROW_HEADER_LEN_MAX +
@@ -150,9 +150,9 @@ xrow_header_encode(const struct xrow_header *header, struct iovec *out,
 		map_size++;
 	}
 
-	if (header->sync) {
+	if (sync) {
 		d = mp_encode_uint(d, IPROTO_SYNC);
-		d = mp_encode_uint(d, header->sync);
+		d = mp_encode_uint(d, sync);
 		map_size++;
 	}
 
@@ -509,7 +509,7 @@ int
 xrow_to_iovec(const struct xrow_header *row, struct iovec *out)
 {
 	assert(mp_sizeof_uint(UINT32_MAX) == 5);
-	int iovcnt = xrow_header_encode(row, out, 5);
+	int iovcnt = xrow_header_encode(row, row->sync, out, 5);
 	if (iovcnt < 0)
 		return -1;
 	ssize_t len = -5;
diff --git a/src/box/xrow.h b/src/box/xrow.h
index 53e650c6d323715881b41fc4ccf5c944707e3578..ee1e9f09db3eeba706a70d40651707637c38692f 100644
--- a/src/box/xrow.h
+++ b/src/box/xrow.h
@@ -78,7 +78,7 @@ struct xrow_header {
  * @post retval <= XROW_IOVMAX
  */
 int
-xrow_header_encode(const struct xrow_header *header,
+xrow_header_encode(const struct xrow_header *header, uint64_t sync,
 		   struct iovec *out, size_t fixheader_len);
 
 /**
diff --git a/test/unit/xrow.cc b/test/unit/xrow.cc
index f73b33fde631da819588cc03aace14baaa11b046..c41724e415b6618d236435dda736b471c5908fd4 100644
--- a/test/unit/xrow.cc
+++ b/test/unit/xrow.cc
@@ -203,7 +203,7 @@ test_greeting()
 void
 test_xrow_header_encode_decode()
 {
-	plan(9);
+	plan(10);
 	struct xrow_header header;
 	char buffer[2048];
 	char *pos = mp_encode_uint(buffer, 300);
@@ -215,11 +215,12 @@ test_xrow_header_encode_decode()
 	header.lsn = 400;
 	header.tm = 123.456;
 	header.bodycnt = 0;
+	uint64_t sync = 100500;
 	struct iovec vec;
-	is(1, xrow_header_encode(&header, &vec, 200), "encode");
+	is(1, xrow_header_encode(&header, sync, &vec, 200), "encode");
 	int fixheader_len = 200;
 	pos = (char *)vec.iov_base + fixheader_len;
-	is(mp_decode_map((const char **)&pos), 4, "header map size");
+	is(mp_decode_map((const char **)&pos), 5, "header map size");
 
 	struct xrow_header decoded_header;
 	const char *begin = (const char *)vec.iov_base;
@@ -232,6 +233,7 @@ test_xrow_header_encode_decode()
 	is(header.replica_id, decoded_header.replica_id, "decoded replica_id");
 	is(header.lsn, decoded_header.lsn, "decoded lsn");
 	is(header.tm, decoded_header.tm, "decoded tm");
+	is(decoded_header.sync, sync, "decoded sync");
 	is(decoded_header.bodycnt, 0, "decoded bodycnt");
 
 	check_plan();
diff --git a/test/unit/xrow.result b/test/unit/xrow.result
index 69230916e6602522c17f27f46b0cf9f9bd6441f6..88500f75e6fe2e0e92091589b41bfdfce9f6fcf7 100644
--- a/test/unit/xrow.result
+++ b/test/unit/xrow.result
@@ -41,7 +41,7 @@
     ok 39 - invalid 10
     ok 40 - invalid 11
 ok 1 - subtests
-    1..9
+    1..10
     ok 1 - bad msgpack end
     ok 2 - encode
     ok 3 - header map size
@@ -50,5 +50,6 @@ ok 1 - subtests
     ok 6 - decoded replica_id
     ok 7 - decoded lsn
     ok 8 - decoded tm
-    ok 9 - decoded bodycnt
+    ok 9 - decoded sync
+    ok 10 - decoded bodycnt
 ok 2 - subtests
diff --git a/test/xlog/misc.result b/test/xlog/misc.result
new file mode 100644
index 0000000000000000000000000000000000000000..120ff70c80829aecc3f6628eee2ac144818726cf
--- /dev/null
+++ b/test/xlog/misc.result
@@ -0,0 +1,78 @@
+test_run = require('test_run').new()
+---
+...
+test_run:cmd('restart server default with cleanup=1')
+fio = require('fio')
+---
+...
+xlog = require('xlog')
+---
+...
+netbox = require('net.box')
+---
+...
+box.schema.user.grant('guest', 'read,write,execute', 'universe')
+---
+...
+--
+-- Check that xlogs doesn't contain IPROTO_SYNC
+--
+conn = netbox.connect(box.cfg.listen)
+---
+...
+-- insert some row using the binary protocol
+conn.space._schema:insert({'test'})
+---
+- ['test']
+...
+-- rotate xlog
+box.snapshot()
+---
+- ok
+...
+-- dump xlog
+xlog_path = fio.pathjoin(box.cfg.wal_dir, string.format("%020d.xlog", 0))
+---
+...
+result = {}
+---
+...
+fun, param, state = xlog.pairs(xlog_path)
+---
+...
+-- skip grants until our insert into _schema
+repeat state, row = fun(param, state) until row.BODY.space_id == box.space._schema.id
+---
+...
+row.HEADER.type
+---
+- INSERT
+...
+row.HEADER.sync
+---
+- null
+...
+row.BODY
+---
+- space_id: 272
+  tuple: ['test']
+...
+box.space._schema:delete('test')
+---
+- ['test']
+...
+--
+-- Clean up
+--
+box.schema.user.revoke('guest', 'read,write,execute', 'universe')
+---
+...
+netbox = nil
+---
+...
+xlog = nil
+---
+...
+fio = nil
+---
+...
diff --git a/test/xlog/misc.test.lua b/test/xlog/misc.test.lua
new file mode 100644
index 0000000000000000000000000000000000000000..6f65c1370b174d6499b1c9b47c8036a37cec6872
--- /dev/null
+++ b/test/xlog/misc.test.lua
@@ -0,0 +1,36 @@
+test_run = require('test_run').new()
+test_run:cmd('restart server default with cleanup=1')
+
+fio = require('fio')
+xlog = require('xlog')
+netbox = require('net.box')
+
+box.schema.user.grant('guest', 'read,write,execute', 'universe')
+
+--
+-- Check that xlogs doesn't contain IPROTO_SYNC
+--
+
+conn = netbox.connect(box.cfg.listen)
+-- insert some row using the binary protocol
+conn.space._schema:insert({'test'})
+-- rotate xlog
+box.snapshot()
+-- dump xlog
+xlog_path = fio.pathjoin(box.cfg.wal_dir, string.format("%020d.xlog", 0))
+result = {}
+fun, param, state = xlog.pairs(xlog_path)
+-- skip grants until our insert into _schema
+repeat state, row = fun(param, state) until row.BODY.space_id == box.space._schema.id
+row.HEADER.type
+row.HEADER.sync
+row.BODY
+box.space._schema:delete('test')
+
+--
+-- Clean up
+--
+box.schema.user.revoke('guest', 'read,write,execute', 'universe')
+netbox = nil
+xlog = nil
+fio = nil