diff --git a/src/box/CMakeLists.txt b/src/box/CMakeLists.txt
index d3b1b038356c6c4fcdae6b001c4ade94534ce935..4fd2250d9b61acbb1dd2e1400fa19c5fd5a9d4be 100644
--- a/src/box/CMakeLists.txt
+++ b/src/box/CMakeLists.txt
@@ -26,6 +26,7 @@ add_library(box STATIC
     error.cc
     xrow.cc
     xlog.cc
+    tuple_format.cc
     tuple.cc
     tuple_convert.cc
     tuple_update.cc
diff --git a/src/box/tuple.cc b/src/box/tuple.cc
index d19468dbdcc5f970c7b46b4fab335e9d464e8db8..af75518b813ac376d27460ee0ac87ba2935d2075 100644
--- a/src/box/tuple.cc
+++ b/src/box/tuple.cc
@@ -35,13 +35,6 @@
 
 #include "fiber.h"
 
-/** Global table of tuple formats */
-struct tuple_format **tuple_formats;
-struct tuple_format *tuple_format_ber;
-static intptr_t recycled_format_ids = FORMAT_ID_NIL;
-
-static uint32_t formats_size, formats_capacity;
-
 uint32_t snapshot_version;
 
 struct quota memtx_quota;
@@ -67,156 +60,6 @@ static struct mempool tuple_iterator_pool;
  */
 struct tuple *box_tuple_last;
 
-/** Extract all available type info from keys. */
-static void
-field_type_create(struct tuple_format *format, struct rlist *key_list)
-{
-	/* There may be fields between indexed fields (gaps). */
-	for (uint32_t i = 0; i < format->field_count; i++)
-		format->fields[i].type = UNKNOWN;
-
-	struct key_def *key_def;
-	/* extract field type info */
-	rlist_foreach_entry(key_def, key_list, link) {
-		for (uint32_t i = 0; i < key_def->part_count; i++) {
-			assert(key_def->parts[i].fieldno < format->field_count);
-			enum field_type set_type = key_def->parts[i].type;
-			enum field_type *fmt_type =
-				&format->fields[key_def->parts[i].fieldno].type;
-			if (*fmt_type != UNKNOWN && *fmt_type != set_type) {
-				tnt_raise(ClientError,
-					  ER_FIELD_TYPE_MISMATCH,
-					  key_def->name,
-					  i + INDEX_OFFSET,
-					  field_type_strs[set_type],
-					  field_type_strs[*fmt_type]);
-			}
-			*fmt_type = set_type;
-		}
-	}
-}
-
-static void
-tuple_format_register(struct tuple_format *format)
-{
-	if (recycled_format_ids != FORMAT_ID_NIL) {
-
-		format->id = (uint16_t) recycled_format_ids;
-		recycled_format_ids = (intptr_t) tuple_formats[recycled_format_ids];
-	} else {
-		if (formats_size == formats_capacity) {
-			uint32_t new_capacity = formats_capacity ?
-				formats_capacity * 2 : 16;
-			struct tuple_format **formats;
-			formats = (struct tuple_format **)
-				realloc(tuple_formats, new_capacity *
-					sizeof(tuple_formats[0]));
-			if (formats == NULL)
-				tnt_raise(OutOfMemory,
-					  sizeof(struct tuple_format),
-					  "malloc", "tuple_formats");
-
-			formats_capacity = new_capacity;
-			tuple_formats = formats;
-		}
-		if (formats_size == FORMAT_ID_MAX + 1) {
-			tnt_raise(LoggedError, ER_TUPLE_FORMAT_LIMIT,
-				  (unsigned) formats_capacity);
-		}
-		format->id = formats_size++;
-	}
-	tuple_formats[format->id] = format;
-}
-
-static void
-tuple_format_deregister(struct tuple_format *format)
-{
-	if (format->id == FORMAT_ID_NIL)
-		return;
-	tuple_formats[format->id] = (struct tuple_format *) recycled_format_ids;
-	recycled_format_ids = format->id;
-	format->id = FORMAT_ID_NIL;
-}
-
-static struct tuple_format *
-tuple_format_alloc(struct rlist *key_list)
-{
-	struct key_def *key_def;
-	uint32_t max_fieldno = 0;
-	uint32_t key_count = 0;
-
-	/* find max max field no */
-	rlist_foreach_entry(key_def, key_list, link) {
-		struct key_part *part = key_def->parts;
-		struct key_part *pend = part + key_def->part_count;
-		key_count++;
-		for (; part < pend; part++)
-			max_fieldno = MAX(max_fieldno, part->fieldno);
-	}
-	uint32_t field_count = key_count > 0 ? max_fieldno + 1 : 0;
-
-	uint32_t total = sizeof(struct tuple_format) +
-		field_count * sizeof(struct tuple_field_format);
-
-	struct tuple_format *format = (struct tuple_format *) malloc(total);
-
-	if (format == NULL)
-		tnt_raise(OutOfMemory, sizeof(struct tuple_format),
-			  "malloc", "tuple format");
-
-	format->refs = 0;
-	format->id = FORMAT_ID_NIL;
-	format->field_count = field_count;
-	return format;
-}
-
-void
-tuple_format_delete(struct tuple_format *format)
-{
-	tuple_format_deregister(format);
-	free(format);
-}
-
-struct tuple_format *
-tuple_format_new(struct rlist *key_list)
-{
-	struct tuple_format *format = tuple_format_alloc(key_list);
-
-	try {
-		tuple_format_register(format);
-		field_type_create(format, key_list);
-	} catch (Exception *e) {
-		tuple_format_delete(format);
-		throw;
-	}
-
-	/* Set up offset slots */
-	if (format->field_count == 0) {
-		/* Nothing to store */
-		format->field_map_size = 0;
-		return format;
-	}
-	/**
-	 * First field is always simply accessible,
-	 * so we don't store offset for it
-	 */
-	format->fields[0].offset_slot = INT32_MAX;
-
-	int current_slot = 0;
-	for (uint32_t i = 1; i < format->field_count; i++) {
-		/*
-		 * In the tuple, store only offsets necessary to
-		 * quickly access indexed fields.
-		 */
-		if (format->fields[i].type == UNKNOWN)
-			format->fields[i].offset_slot = INT32_MAX;
-		else
-			format->fields[i].offset_slot = --current_slot;
-	}
-	format->field_map_size = -current_slot * sizeof(uint32_t);
-	return format;
-}
-
 /*
  * Validate a new tuple format and initialize tuple-local
  * format data.
@@ -658,10 +501,7 @@ void
 tuple_init(float tuple_arena_max_size, uint32_t objsize_min,
 	   uint32_t objsize_max, float alloc_factor)
 {
-	RLIST_HEAD(empty_list);
-	tuple_format_ber = tuple_format_new(&empty_list);
-	/* Make sure this one stays around. */
-	tuple_format_ref(tuple_format_ber, 1);
+	tuple_format_init();
 
 	/* Apply lowest allowed objsize bounds */
 	if (objsize_min < OBJSIZE_MIN)
@@ -711,19 +551,6 @@ tuple_free()
 	}
 
 	mempool_destroy(&tuple_iterator_pool);
-
-	/* Clear recycled ids. */
-	while (recycled_format_ids != FORMAT_ID_NIL) {
-
-		uint16_t id = (uint16_t) recycled_format_ids;
-		recycled_format_ids = (intptr_t) tuple_formats[id];
-		tuple_formats[id] = NULL;
-	}
-	for (struct tuple_format **format = tuple_formats;
-	     format < tuple_formats + formats_size;
-	     format++)
-		free(*format); /* ignore the reference count. */
-	free(tuple_formats);
 }
 
 void
diff --git a/src/box/tuple.h b/src/box/tuple.h
index b537ed045625257a4e00ee683620b3b4113c28ff..8ed32d6ed940e9a814ae1ec53f4868a97eee2961 100644
--- a/src/box/tuple.h
+++ b/src/box/tuple.h
@@ -32,6 +32,8 @@
  */
 #include "trivia/util.h"
 
+#include "tuple_format.h"
+
 #if defined(__cplusplus)
 extern "C" {
 #endif /* defined(__cplusplus) */
@@ -257,14 +259,7 @@ box_tuple_upsert(const box_tuple_t *tuple, const char *expr, const
 #include "tuple_update.h"
 #include "errinj.h"
 
-enum { FORMAT_ID_MAX = UINT16_MAX - 1, FORMAT_ID_NIL = UINT16_MAX };
-enum { FORMAT_REF_MAX = INT32_MAX, TUPLE_REF_MAX = UINT16_MAX };
-/*
- * We don't pass INDEX_OFFSET around dynamically all the time,
- * at least hard code it so that in most cases it's a nice error
- * message
- */
-enum { INDEX_OFFSET = 1 };
+enum { TUPLE_REF_MAX = UINT16_MAX };
 
 /** Common quota for tuples and indexes */
 extern struct quota memtx_quota;
@@ -273,102 +268,6 @@ extern struct small_alloc memtx_alloc;
 /** Tuple slab arena */
 extern struct slab_arena memtx_arena;
 
-/**
- * @brief In-memory tuple format
- */
-
-/**
- * @brief Tuple field format
- * Support structure for struct tuple_format.
- * Contains information of one field.
- */
-struct tuple_field_format {
-	/**
-	 * Field type of an indexed field.
-	 * If a field participates in at least one of space indexes
-	 * then its type is stored in this member.
-	 * If a field does not participate in an index
-	 * then UNKNOWN is stored for it.
-	 */
-	enum field_type type;
-	/**
-	 * Offset slot in field map in tuple.
-	 * Normally tuple stores field map - offsets of all fields
-	 * participating in indexes. This allows quick access to most
-	 * used fields without parsing entire mspack.
-	 * This member stores position in the field map of tuple
-	 * for current field.
-	 * If the field does not participate in indexes then it has
-	 * no offset in field map and INT_MAX is stored in this member.
-	 * Due to specific field map in tuple (it is stored before tuple),
-	 * the positions in field map is negative.
-	 * Thus if this member is negative, smth like
-	 * tuple->data[((uint32_t *)tuple)[format->offset_slot[fieldno]]]
-	 * gives the start of the field
-	 */
-	int32_t offset_slot;
-};
-
-/**
- * @brief Tuple format
- * Tuple format describes how tuple is stored and information about its fields
- */
-struct tuple_format {
-	uint16_t id;
-	/* Format objects are reference counted. */
-	int refs;
-	/* Length of 'fields' array. */
-	uint32_t field_count;
-	/**
-	 * Size of field map of tuple in bytes.
-	 * See tuple_field_format::ofset for details//
-	 */
-	uint32_t field_map_size;
-
-	/* Formats of the fields */
-	struct tuple_field_format fields[];
-};
-
-extern struct tuple_format **tuple_formats;
-/**
- * Default format for a tuple which does not belong
- * to any space and is stored in memory.
- */
-extern struct tuple_format *tuple_format_ber;
-
-static inline uint32_t
-tuple_format_id(struct tuple_format *format)
-{
-	assert(tuple_formats[format->id] == format);
-	return format->id;
-}
-
-/**
- * @brief Allocate, construct and register a new in-memory tuple
- *	 format.
- * @param space description
- *
- * @return tuple format or raise an exception on error
- */
-struct tuple_format *
-tuple_format_new(struct rlist *key_list);
-
-/** Delete a format with zero ref count. */
-void
-tuple_format_delete(struct tuple_format *format);
-
-static inline void
-tuple_format_ref(struct tuple_format *format, int count)
-{
-	assert(format->refs + count >= 0);
-	assert((uint64_t)format->refs + count <= FORMAT_REF_MAX);
-
-	format->refs += count;
-	if (format->refs == 0)
-		tuple_format_delete(format);
-
-};
-
 /**
  * An atom of Tarantool storage. Represents MsgPack Array.
  */
@@ -509,7 +408,7 @@ struct TupleRefNil {
 static inline struct tuple_format *
 tuple_format(const struct tuple *tuple)
 {
-	struct tuple_format *format = tuple_formats[tuple->format_id];
+	struct tuple_format *format = tuple_format_by_id(tuple->format_id);
 	assert(tuple_format_id(format) == tuple->format_id);
 	return format;
 }
diff --git a/src/box/tuple_format.cc b/src/box/tuple_format.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b2fefc25aa1577afc5a8dafbaf60643e3bdea495
--- /dev/null
+++ b/src/box/tuple_format.cc
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2010-2016, Tarantool AUTHORS, please see AUTHORS file.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the
+ *    following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include "tuple_format.h"
+
+/** Global table of tuple formats */
+struct tuple_format **tuple_formats;
+struct tuple_format *tuple_format_ber;
+static intptr_t recycled_format_ids = FORMAT_ID_NIL;
+
+static uint32_t formats_size = 0, formats_capacity = 0;
+
+/** Extract all available type info from keys. */
+static void
+field_type_create(struct tuple_format *format, struct rlist *key_list)
+{
+	/* There may be fields between indexed fields (gaps). */
+	for (uint32_t i = 0; i < format->field_count; i++)
+		format->fields[i].type = UNKNOWN;
+
+	struct key_def *key_def;
+	/* extract field type info */
+	rlist_foreach_entry(key_def, key_list, link) {
+		for (uint32_t i = 0; i < key_def->part_count; i++) {
+			assert(key_def->parts[i].fieldno < format->field_count);
+			enum field_type set_type = key_def->parts[i].type;
+			enum field_type *fmt_type =
+				&format->fields[key_def->parts[i].fieldno].type;
+			if (*fmt_type != UNKNOWN && *fmt_type != set_type) {
+				tnt_raise(ClientError,
+					  ER_FIELD_TYPE_MISMATCH,
+					  key_def->name,
+					  i + INDEX_OFFSET,
+					  field_type_strs[set_type],
+					  field_type_strs[*fmt_type]);
+			}
+			*fmt_type = set_type;
+		}
+	}
+}
+
+static void
+tuple_format_register(struct tuple_format *format)
+{
+	if (recycled_format_ids != FORMAT_ID_NIL) {
+
+		format->id = (uint16_t) recycled_format_ids;
+		recycled_format_ids = (intptr_t) tuple_formats[recycled_format_ids];
+	} else {
+		if (formats_size == formats_capacity) {
+			uint32_t new_capacity = formats_capacity ?
+						formats_capacity * 2 : 16;
+			struct tuple_format **formats;
+			formats = (struct tuple_format **)
+				realloc(tuple_formats, new_capacity *
+						       sizeof(tuple_formats[0]));
+			if (formats == NULL)
+				tnt_raise(OutOfMemory,
+					  sizeof(struct tuple_format),
+					  "malloc", "tuple_formats");
+
+			formats_capacity = new_capacity;
+			tuple_formats = formats;
+		}
+		if (formats_size == FORMAT_ID_MAX + 1) {
+			tnt_raise(LoggedError, ER_TUPLE_FORMAT_LIMIT,
+				  (unsigned) formats_capacity);
+		}
+		format->id = formats_size++;
+	}
+	tuple_formats[format->id] = format;
+}
+
+static void
+tuple_format_deregister(struct tuple_format *format)
+{
+	if (format->id == FORMAT_ID_NIL)
+		return;
+	tuple_formats[format->id] = (struct tuple_format *) recycled_format_ids;
+	recycled_format_ids = format->id;
+	format->id = FORMAT_ID_NIL;
+}
+
+static struct tuple_format *
+tuple_format_alloc(struct rlist *key_list)
+{
+	struct key_def *key_def;
+	uint32_t max_fieldno = 0;
+	uint32_t key_count = 0;
+
+	/* find max max field no */
+	rlist_foreach_entry(key_def, key_list, link) {
+		struct key_part *part = key_def->parts;
+		struct key_part *pend = part + key_def->part_count;
+		key_count++;
+		for (; part < pend; part++)
+			max_fieldno = MAX(max_fieldno, part->fieldno);
+	}
+	uint32_t field_count = key_count > 0 ? max_fieldno + 1 : 0;
+
+	uint32_t total = sizeof(struct tuple_format) +
+			 field_count * sizeof(struct tuple_field_format);
+
+	struct tuple_format *format = (struct tuple_format *) malloc(total);
+
+	if (format == NULL)
+		tnt_raise(OutOfMemory, sizeof(struct tuple_format),
+			  "malloc", "tuple format");
+
+	format->refs = 0;
+	format->id = FORMAT_ID_NIL;
+	format->field_count = field_count;
+	return format;
+}
+
+void
+tuple_format_delete(struct tuple_format *format)
+{
+	tuple_format_deregister(format);
+	free(format);
+}
+
+struct tuple_format *
+tuple_format_new(struct rlist *key_list)
+{
+	struct tuple_format *format = tuple_format_alloc(key_list);
+
+	try {
+		tuple_format_register(format);
+		field_type_create(format, key_list);
+	} catch (Exception *e) {
+		tuple_format_delete(format);
+		throw;
+	}
+
+	/* Set up offset slots */
+	if (format->field_count == 0) {
+		/* Nothing to store */
+		format->field_map_size = 0;
+		return format;
+	}
+	/**
+	 * First field is always simply accessible,
+	 * so we don't store offset for it
+	 */
+	format->fields[0].offset_slot = INT32_MAX;
+
+	int current_slot = 0;
+	for (uint32_t i = 1; i < format->field_count; i++) {
+		/*
+		 * In the tuple, store only offsets necessary to
+		 * quickly access indexed fields.
+		 */
+		if (format->fields[i].type == UNKNOWN)
+			format->fields[i].offset_slot = INT32_MAX;
+		else
+			format->fields[i].offset_slot = --current_slot;
+	}
+	format->field_map_size = -current_slot * sizeof(uint32_t);
+	return format;
+}
+
+void
+tuple_format_init()
+{
+	RLIST_HEAD(empty_list);
+	tuple_format_ber = tuple_format_new(&empty_list);
+	/* Make sure this one stays around. */
+	tuple_format_ref(tuple_format_ber, 1);
+}
+
+/** Destroy tuple format subsystem and free resourses */
+void
+tuple_format_free()
+{
+	/* Clear recycled ids. */
+	while (recycled_format_ids != FORMAT_ID_NIL) {
+		uint16_t id = (uint16_t) recycled_format_ids;
+		recycled_format_ids = (intptr_t) tuple_formats[id];
+		tuple_formats[id] = NULL;
+	}
+	for (struct tuple_format **format = tuple_formats;
+	     format < tuple_formats + formats_size;
+	     format++)
+		free(*format); /* ignore the reference count. */
+	free(tuple_formats);
+}
diff --git a/src/box/tuple_format.h b/src/box/tuple_format.h
new file mode 100644
index 0000000000000000000000000000000000000000..884be395d820eef2d15273723b53da162f3eec9f
--- /dev/null
+++ b/src/box/tuple_format.h
@@ -0,0 +1,153 @@
+#ifndef TARANTOOL_BOX_TUPLE_FORMAT_H_INCLUDED
+#define TARANTOOL_BOX_TUPLE_FORMAT_H_INCLUDED
+/*
+ * Copyright 2010-2016, Tarantool AUTHORS, please see AUTHORS file.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the
+ *    following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "key_def.h" /* for enum field_type */
+
+enum { FORMAT_ID_MAX = UINT16_MAX - 1, FORMAT_ID_NIL = UINT16_MAX };
+enum { FORMAT_REF_MAX = INT32_MAX};
+
+/*
+ * We don't pass INDEX_OFFSET around dynamically all the time,
+ * at least hard code it so that in most cases it's a nice error
+ * message
+ */
+enum { INDEX_OFFSET = 1 };
+
+
+/**
+ * @brief Tuple field format
+ * Support structure for struct tuple_format.
+ * Contains information of one field.
+ */
+struct tuple_field_format {
+	/**
+	 * Field type of an indexed field.
+	 * If a field participates in at least one of space indexes
+	 * then its type is stored in this member.
+	 * If a field does not participate in an index
+	 * then UNKNOWN is stored for it.
+	 */
+	enum field_type type;
+	/**
+	 * Offset slot in field map in tuple.
+	 * Normally tuple stores field map - offsets of all fields
+	 * participating in indexes. This allows quick access to most
+	 * used fields without parsing entire mspack.
+	 * This member stores position in the field map of tuple
+	 * for current field.
+	 * If the field does not participate in indexes then it has
+	 * no offset in field map and INT_MAX is stored in this member.
+	 * Due to specific field map in tuple (it is stored before tuple),
+	 * the positions in field map is negative.
+	 * Thus if this member is negative, smth like
+	 * tuple->data[((uint32_t *)tuple)[format->offset_slot[fieldno]]]
+	 * gives the start of the field
+	 */
+	int32_t offset_slot;
+};
+
+/**
+ * @brief Tuple format
+ * Tuple format describes how tuple is stored and information about its fields
+ */
+struct tuple_format {
+	uint16_t id;
+	/* Format objects are reference counted. */
+	int refs;
+	/* Length of 'fields' array. */
+	uint32_t field_count;
+	/**
+	 * Size of field map of tuple in bytes.
+	 * See tuple_field_format::ofset for details//
+	 */
+	uint32_t field_map_size;
+
+	/* Formats of the fields */
+	struct tuple_field_format fields[];
+};
+
+/**
+ * Default format for a tuple which does not belong
+ * to any space and is stored in memory.
+ */
+extern struct tuple_format *tuple_format_ber;
+
+extern struct tuple_format **tuple_formats;
+
+static inline uint32_t
+tuple_format_id(struct tuple_format *format)
+{
+	assert(tuple_formats[format->id] == format);
+	return format->id;
+}
+
+static inline struct tuple_format *
+tuple_format_by_id(uint32_t tuple_format_id)
+{
+	return tuple_formats[tuple_format_id];
+}
+
+/**
+ * @brief Allocate, construct and register a new in-memory tuple
+ *	 format.
+ * @param space description
+ *
+ * @return tuple format or raise an exception on error
+ */
+struct tuple_format *
+tuple_format_new(struct rlist *key_list);
+
+/** Delete a format with zero ref count. */
+void
+tuple_format_delete(struct tuple_format *format);
+
+static inline void
+tuple_format_ref(struct tuple_format *format, int count)
+{
+	assert(format->refs + count >= 0);
+	assert((uint64_t)format->refs + count <= FORMAT_REF_MAX);
+
+	format->refs += count;
+	if (format->refs == 0)
+		tuple_format_delete(format);
+
+};
+
+void
+tuple_format_init();
+
+/** Destroy tuple format subsystem and free resourses */
+void
+tuple_format_free();
+
+#endif /* #ifndef TARANTOOL_BOX_TUPLE_FORMAT_H_INCLUDED */