diff --git a/src/schema.rs b/src/schema.rs
index 1417a7cf7e321c90c03b1e236d72e7a5900d06ee..72b9a0257b518b1def954895c618782a79c8ee28 100644
--- a/src/schema.rs
+++ b/src/schema.rs
@@ -2,6 +2,8 @@ use crate::storage::set_pico_schema_version;
 use crate::traft;
 use crate::traft::op::Ddl;
 use serde::{Deserialize, Serialize};
+use std::borrow::Cow;
+use std::collections::BTreeMap;
 use tarantool::{
     index::Metadata as IndexMetadata,
     index::{IndexId, Part},
@@ -115,6 +117,7 @@ pub struct IndexDef {
     pub parts: Vec<Part>,
     pub schema_version: u64,
     pub operable: bool,
+    pub unique: bool,
 }
 impl Encode for IndexDef {}
 
@@ -125,12 +128,14 @@ impl IndexDef {
     pub fn to_index_metadata(&self) -> IndexMetadata {
         use tarantool::index::IndexType;
 
+        let mut opts = BTreeMap::new();
+        opts.insert(Cow::from("unique"), Value::Bool(self.unique));
         let index_meta = IndexMetadata {
             space_id: self.space_id,
             index_id: self.id,
             name: self.name.as_str().into(),
             r#type: IndexType::Tree,
-            opts: Default::default(),
+            opts,
             parts: self.parts.clone(),
         };
 
diff --git a/src/storage.rs b/src/storage.rs
index cf7f7ec70bf9d4f4eacb5f7e08468f108da75e34..983549fac487765acbe36e7a506012f76b7aba7c 100644
--- a/src/storage.rs
+++ b/src/storage.rs
@@ -1392,6 +1392,7 @@ impl Indexes {
             .field(("parts", FieldType::Array))
             .field(("schema_version", FieldType::Unsigned))
             .field(("operable", FieldType::Boolean))
+            .field(("unique", FieldType::Boolean))
             .if_not_exists(true)
             .create()?;
 
diff --git a/src/traft/node.rs b/src/traft/node.rs
index d1d346975c929aca09fe8a6676722706fb6df08f..fd24f22b486534b12f40fb42d34b0c8b517b6bc0 100644
--- a/src/traft/node.rs
+++ b/src/traft/node.rs
@@ -972,6 +972,7 @@ impl NodeImpl {
                     parts: primary_key,
                     operable: false,
                     // TODO: support other cases
+                    unique: true,
                     local: true,
                 };
                 self.storage.indexes.insert(&index_def)?;
diff --git a/test/int/test_ddl.py b/test/int/test_ddl.py
index 992689ee54419f72bf16114f9e932e93139cfec1..940223bb291eb084a263d18ee718791ef0ea4da6 100644
--- a/test/int/test_ddl.py
+++ b/test/int/test_ddl.py
@@ -87,6 +87,7 @@ def test_ddl_create_space_bulky(cluster: Cluster):
         [[1, "unsigned", None, None, None]],
         2,
         True,
+        True,
     ]
     assert i1.call("box.space._pico_index:get", [666, 0]) == index_info
     assert i2.call("box.space._pico_index:get", [666, 0]) == index_info
@@ -96,7 +97,7 @@ def test_ddl_create_space_bulky(cluster: Cluster):
         0,
         "primary_key",
         "tree",
-        dict(),
+        dict(unique=True),
         [[1, "unsigned", None, None, None]],
     ]
     assert i1.call("box.space._index:get", [666, 0]) == index_meta
@@ -208,7 +209,7 @@ def test_ddl_from_snapshot(cluster: Cluster):
         0,
         "primary_key",
         "tree",
-        dict(),
+        dict(unique=True),
         [[1, "unsigned", None, None, None]],
     ]
     assert i1.call("box.space._index:get", [666, 0]) == index_meta