diff --git a/src/database/graph_db_accessor.cpp b/src/database/graph_db_accessor.cpp
index 7f837466f..ca3346a0d 100644
--- a/src/database/graph_db_accessor.cpp
+++ b/src/database/graph_db_accessor.cpp
@@ -219,9 +219,9 @@ void GraphDbAccessor::EnableIndex(const LabelPropertyIndex::Key &key) {
   // built at this point even if this DBA's transaction aborts for some
   // reason.
   auto wal_build_index_tx_id = transaction_id();
-  wal().Emplace(database::StateDelta::BuildIndex(wal_build_index_tx_id,
-                                                 LabelName(key.label_),
-                                                 PropertyName(key.property_)));
+  wal().Emplace(database::StateDelta::BuildIndex(
+      wal_build_index_tx_id, key.label_, LabelName(key.label_), key.property_,
+      PropertyName(key.property_)));
 
   // After these two operations we are certain that everything is contained in
   // the index under the assumption that the original index creation transaction
@@ -419,7 +419,7 @@ EdgeAccessor GraphDbAccessor::InsertEdge(
     // outcomes are success or error (serialization, timeout).
   }
   wal().Emplace(database::StateDelta::CreateEdge(
-      transaction_.id_, edge_vlist->gid_, from.gid(), to.gid(),
+      transaction_.id_, edge_vlist->gid_, from.gid(), to.gid(), edge_type,
       EdgeTypeName(edge_type)));
   return EdgeAccessor(edge_vlist, *this, from.address(), to.address(),
                       edge_type);
diff --git a/src/database/state_delta.cpp b/src/database/state_delta.cpp
index cdf301910..ac1c25da2 100644
--- a/src/database/state_delta.cpp
+++ b/src/database/state_delta.cpp
@@ -6,12 +6,6 @@
 
 namespace database {
 
-std::pair<std::string, std::string> StateDelta::IndexName() const {
-  CHECK(StateDelta::type() == StateDelta::Type::BUILD_INDEX)
-      << "Invalid operation type to try to get index name";
-  return std::make_pair(label_, property_);
-}
-
 StateDelta StateDelta::TxBegin(tx::transaction_id_t tx_id) {
   return {StateDelta::Type::TRANSACTION_BEGIN, tx_id};
 }
@@ -27,128 +21,147 @@ StateDelta StateDelta::TxAbort(tx::transaction_id_t tx_id) {
 StateDelta StateDelta::CreateVertex(tx::transaction_id_t tx_id,
                                     gid::Gid vertex_id) {
   StateDelta op(StateDelta::Type::CREATE_VERTEX, tx_id);
-  op.vertex_id_ = vertex_id;
+  op.vertex_id = vertex_id;
   return op;
 }
 
 StateDelta StateDelta::CreateEdge(tx::transaction_id_t tx_id, gid::Gid edge_id,
                                   gid::Gid vertex_from_id,
                                   gid::Gid vertex_to_id,
-                                  const std::string &edge_type) {
+                                  storage::EdgeType edge_type,
+                                  const std::string &edge_type_name) {
   StateDelta op(StateDelta::Type::CREATE_EDGE, tx_id);
-  op.edge_id_ = edge_id;
-  op.vertex_from_id_ = vertex_from_id;
-  op.vertex_to_id_ = vertex_to_id;
-  op.edge_type_ = edge_type;
+  op.edge_id = edge_id;
+  op.vertex_from_id = vertex_from_id;
+  op.vertex_to_id = vertex_to_id;
+  op.edge_type = edge_type;
+  op.edge_type_name = edge_type_name;
   return op;
 }
 
 StateDelta StateDelta::PropsSetVertex(tx::transaction_id_t tx_id,
                                       gid::Gid vertex_id,
-                                      const std::string &property,
+                                      storage::Property property,
+                                      const std::string &property_name,
                                       const PropertyValue &value) {
   StateDelta op(StateDelta::Type::SET_PROPERTY_VERTEX, tx_id);
-  op.vertex_id_ = vertex_id;
-  op.property_ = property;
-  op.value_ = value;
+  op.vertex_id = vertex_id;
+  op.property = property;
+  op.property_name = property_name;
+  op.value = value;
   return op;
 }
 
 StateDelta StateDelta::PropsSetEdge(tx::transaction_id_t tx_id,
                                     gid::Gid edge_id,
-                                    const std::string &property,
+                                    storage::Property property,
+                                    const std::string &property_name,
                                     const PropertyValue &value) {
   StateDelta op(StateDelta::Type::SET_PROPERTY_EDGE, tx_id);
-  op.edge_id_ = edge_id;
-  op.property_ = property;
-  op.value_ = value;
+  op.edge_id = edge_id;
+  op.property = property;
+  op.property_name = property_name;
+  op.value = value;
   return op;
 }
 
 StateDelta StateDelta::AddLabel(tx::transaction_id_t tx_id, gid::Gid vertex_id,
-                                const std::string &label) {
+                                storage::Label label,
+                                const std::string &label_name) {
   StateDelta op(StateDelta::Type::ADD_LABEL, tx_id);
-  op.vertex_id_ = vertex_id;
-  op.label_ = label;
+  op.vertex_id = vertex_id;
+  op.label = label;
+  op.label_name = label_name;
   return op;
 }
 
 StateDelta StateDelta::RemoveLabel(tx::transaction_id_t tx_id,
-                                   gid::Gid vertex_id,
-                                   const std::string &label) {
+                                   gid::Gid vertex_id, storage::Label label,
+                                   const std::string &label_name) {
   StateDelta op(StateDelta::Type::REMOVE_LABEL, tx_id);
-  op.vertex_id_ = vertex_id;
-  op.label_ = label;
+  op.vertex_id = vertex_id;
+  op.label = label;
+  op.label_name = label_name;
   return op;
 }
 
 StateDelta StateDelta::RemoveVertex(tx::transaction_id_t tx_id,
                                     gid::Gid vertex_id) {
   StateDelta op(StateDelta::Type::REMOVE_VERTEX, tx_id);
-  op.vertex_id_ = vertex_id;
+  op.vertex_id = vertex_id;
   return op;
 }
 
 StateDelta StateDelta::RemoveEdge(tx::transaction_id_t tx_id,
                                   gid::Gid edge_id) {
   StateDelta op(StateDelta::Type::REMOVE_EDGE, tx_id);
-  op.edge_id_ = edge_id;
+  op.edge_id = edge_id;
   return op;
 }
 
 StateDelta StateDelta::BuildIndex(tx::transaction_id_t tx_id,
-                                  const std::string &label,
-                                  const std::string &property) {
+                                  storage::Label label,
+                                  const std::string &label_name,
+                                  storage::Property property,
+                                  const std::string &property_name) {
   StateDelta op(StateDelta::Type::BUILD_INDEX, tx_id);
-  op.label_ = label;
-  op.property_ = property;
+  op.label = label;
+  op.label_name = label_name;
+  op.property = property;
+  op.property_name = property_name;
   return op;
 }
 
 void StateDelta::Encode(
     HashedFileWriter &writer,
     communication::bolt::PrimitiveEncoder<HashedFileWriter> &encoder) const {
-  encoder.WriteInt(static_cast<int64_t>(type_));
-  encoder.WriteInt(static_cast<int64_t>(transaction_id_));
+  encoder.WriteInt(static_cast<int64_t>(type));
+  encoder.WriteInt(static_cast<int64_t>(transaction_id));
 
-  switch (type_) {
+  switch (type) {
     case Type::TRANSACTION_BEGIN:
     case Type::TRANSACTION_COMMIT:
     case Type::TRANSACTION_ABORT:
       break;
     case Type::CREATE_VERTEX:
-      encoder.WriteInt(vertex_id_);
+      encoder.WriteInt(vertex_id);
       break;
     case Type::CREATE_EDGE:
-      encoder.WriteInt(edge_id_);
-      encoder.WriteInt(vertex_from_id_);
-      encoder.WriteInt(vertex_to_id_);
-      encoder.WriteString(edge_type_);
+      encoder.WriteInt(edge_id);
+      encoder.WriteInt(vertex_from_id);
+      encoder.WriteInt(vertex_to_id);
+      encoder.WriteInt(edge_type.storage());
+      encoder.WriteString(edge_type_name);
       break;
     case Type::SET_PROPERTY_VERTEX:
-      encoder.WriteInt(vertex_id_);
-      encoder.WriteString(property_);
-      encoder.WritePropertyValue(value_);
+      encoder.WriteInt(vertex_id);
+      encoder.WriteInt(property.storage());
+      encoder.WriteString(property_name);
+      encoder.WritePropertyValue(value);
       break;
     case Type::SET_PROPERTY_EDGE:
-      encoder.WriteInt(edge_id_);
-      encoder.WriteString(property_);
-      encoder.WritePropertyValue(value_);
+      encoder.WriteInt(edge_id);
+      encoder.WriteInt(property.storage());
+      encoder.WriteString(property_name);
+      encoder.WritePropertyValue(value);
       break;
     case Type::ADD_LABEL:
     case Type::REMOVE_LABEL:
-      encoder.WriteInt(vertex_id_);
-      encoder.WriteString(label_);
+      encoder.WriteInt(vertex_id);
+      encoder.WriteInt(label.storage());
+      encoder.WriteString(label_name);
       break;
     case Type::REMOVE_VERTEX:
-      encoder.WriteInt(vertex_id_);
+      encoder.WriteInt(vertex_id);
       break;
     case Type::REMOVE_EDGE:
-      encoder.WriteInt(edge_id_);
+      encoder.WriteInt(edge_id);
       break;
     case Type::BUILD_INDEX:
-      encoder.WriteString(label_);
-      encoder.WriteString(property_);
+      encoder.WriteInt(label.storage());
+      encoder.WriteString(label_name);
+      encoder.WriteInt(property.storage());
+      encoder.WriteString(property_name);
       break;
   }
 
@@ -159,6 +172,10 @@ void StateDelta::Encode(
   if (!decoder.ReadValue(&dv)) return nullopt; \
   r_val.member = dv.value_f();
 
+#define DECODE_MEMBER_CAST(member, value_f, type) \
+  if (!decoder.ReadValue(&dv)) return nullopt;    \
+  r_val.member = static_cast<type>(dv.value_f());
+
 std::experimental::optional<StateDelta> StateDelta::Decode(
     HashedFileReader &reader,
     communication::bolt::Decoder<HashedFileReader> &decoder) {
@@ -170,49 +187,55 @@ std::experimental::optional<StateDelta> StateDelta::Decode(
 
   try {
     if (!decoder.ReadValue(&dv)) return nullopt;
-    r_val.type_ = static_cast<enum StateDelta::Type>(dv.ValueInt());
-    DECODE_MEMBER(transaction_id_, ValueInt)
+    r_val.type = static_cast<enum StateDelta::Type>(dv.ValueInt());
+    DECODE_MEMBER(transaction_id, ValueInt)
 
-    switch (r_val.type_) {
+    switch (r_val.type) {
       case Type::TRANSACTION_BEGIN:
       case Type::TRANSACTION_COMMIT:
       case Type::TRANSACTION_ABORT:
         break;
       case Type::CREATE_VERTEX:
-        DECODE_MEMBER(vertex_id_, ValueInt)
+        DECODE_MEMBER(vertex_id, ValueInt)
         break;
       case Type::CREATE_EDGE:
-        DECODE_MEMBER(edge_id_, ValueInt)
-        DECODE_MEMBER(vertex_from_id_, ValueInt)
-        DECODE_MEMBER(vertex_to_id_, ValueInt)
-        DECODE_MEMBER(edge_type_, ValueString)
+        DECODE_MEMBER(edge_id, ValueInt)
+        DECODE_MEMBER(vertex_from_id, ValueInt)
+        DECODE_MEMBER(vertex_to_id, ValueInt)
+        DECODE_MEMBER_CAST(edge_type, ValueInt, storage::EdgeType)
+        DECODE_MEMBER(edge_type_name, ValueString)
         break;
       case Type::SET_PROPERTY_VERTEX:
-        DECODE_MEMBER(vertex_id_, ValueInt)
-        DECODE_MEMBER(property_, ValueString)
+        DECODE_MEMBER(vertex_id, ValueInt)
+        DECODE_MEMBER_CAST(property, ValueInt, storage::Property)
+        DECODE_MEMBER(property_name, ValueString)
         if (!decoder.ReadValue(&dv)) return nullopt;
-        r_val.value_ = static_cast<PropertyValue>(dv);
+        r_val.value = static_cast<PropertyValue>(dv);
         break;
       case Type::SET_PROPERTY_EDGE:
-        DECODE_MEMBER(edge_id_, ValueInt)
-        DECODE_MEMBER(property_, ValueString)
+        DECODE_MEMBER(edge_id, ValueInt)
+        DECODE_MEMBER_CAST(property, ValueInt, storage::Property)
+        DECODE_MEMBER(property_name, ValueString)
         if (!decoder.ReadValue(&dv)) return nullopt;
-        r_val.value_ = static_cast<PropertyValue>(dv);
+        r_val.value = static_cast<PropertyValue>(dv);
         break;
       case Type::ADD_LABEL:
       case Type::REMOVE_LABEL:
-        DECODE_MEMBER(vertex_id_, ValueInt)
-        DECODE_MEMBER(label_, ValueString)
+        DECODE_MEMBER(vertex_id, ValueInt)
+        DECODE_MEMBER_CAST(label, ValueInt, storage::Label)
+        DECODE_MEMBER(label_name, ValueString)
         break;
       case Type::REMOVE_VERTEX:
-        DECODE_MEMBER(vertex_id_, ValueInt)
+        DECODE_MEMBER(vertex_id, ValueInt)
         break;
       case Type::REMOVE_EDGE:
-        DECODE_MEMBER(edge_id_, ValueInt)
+        DECODE_MEMBER(edge_id, ValueInt)
         break;
       case Type::BUILD_INDEX:
-        DECODE_MEMBER(label_, ValueString)
-        DECODE_MEMBER(property_, ValueString)
+        DECODE_MEMBER_CAST(label, ValueInt, storage::Label)
+        DECODE_MEMBER(label_name, ValueString)
+        DECODE_MEMBER_CAST(property, ValueInt, storage::Property)
+        DECODE_MEMBER(property_name, ValueString)
         break;
     }
 
@@ -232,7 +255,7 @@ std::experimental::optional<StateDelta> StateDelta::Decode(
 #undef DECODE_MEMBER
 
 void StateDelta::Apply(GraphDbAccessor &dba) const {
-  switch (type_) {
+  switch (type) {
     // Transactional state is not recovered.
     case Type::TRANSACTION_BEGIN:
     case Type::TRANSACTION_COMMIT:
@@ -240,48 +263,48 @@ void StateDelta::Apply(GraphDbAccessor &dba) const {
       LOG(FATAL) << "Transaction handling not handled in Apply";
       break;
     case Type::CREATE_VERTEX:
-      dba.InsertVertex(vertex_id_);
+      dba.InsertVertex(vertex_id);
       break;
     case Type::CREATE_EDGE: {
-      auto from = dba.FindVertex(vertex_from_id_, true);
-      auto to = dba.FindVertex(vertex_to_id_, true);
+      auto from = dba.FindVertex(vertex_from_id, true);
+      auto to = dba.FindVertex(vertex_to_id, true);
       DCHECK(from) << "Failed to find vertex.";
       DCHECK(to) << "Failed to find vertex.";
-      dba.InsertEdge(*from, *to, dba.EdgeType(edge_type_), edge_id_);
+      dba.InsertEdge(*from, *to, dba.EdgeType(edge_type_name), edge_id);
       break;
     }
     case Type::SET_PROPERTY_VERTEX: {
-      auto vertex = dba.FindVertex(vertex_id_, true);
+      auto vertex = dba.FindVertex(vertex_id, true);
       DCHECK(vertex) << "Failed to find vertex.";
-      vertex->PropsSet(dba.Property(property_), value_);
+      vertex->PropsSet(dba.Property(property_name), value);
       break;
     }
     case Type::SET_PROPERTY_EDGE: {
-      auto edge = dba.FindEdge(edge_id_, true);
+      auto edge = dba.FindEdge(edge_id, true);
       DCHECK(edge) << "Failed to find edge.";
-      edge->PropsSet(dba.Property(property_), value_);
+      edge->PropsSet(dba.Property(property_name), value);
       break;
     }
     case Type::ADD_LABEL: {
-      auto vertex = dba.FindVertex(vertex_id_, true);
+      auto vertex = dba.FindVertex(vertex_id, true);
       DCHECK(vertex) << "Failed to find vertex.";
-      vertex->add_label(dba.Label(label_));
+      vertex->add_label(dba.Label(label_name));
       break;
     }
     case Type::REMOVE_LABEL: {
-      auto vertex = dba.FindVertex(vertex_id_, true);
+      auto vertex = dba.FindVertex(vertex_id, true);
       DCHECK(vertex) << "Failed to find vertex.";
-      vertex->remove_label(dba.Label(label_));
+      vertex->remove_label(dba.Label(label_name));
       break;
     }
     case Type::REMOVE_VERTEX: {
-      auto vertex = dba.FindVertex(vertex_id_, true);
+      auto vertex = dba.FindVertex(vertex_id, true);
       DCHECK(vertex) << "Failed to find vertex.";
       dba.DetachRemoveVertex(*vertex);
       break;
     }
     case Type::REMOVE_EDGE: {
-      auto edge = dba.FindEdge(edge_id_, true);
+      auto edge = dba.FindEdge(edge_id, true);
       DCHECK(edge) << "Failed to find edge.";
       dba.RemoveEdge(*edge);
       break;
diff --git a/src/database/state_delta.hpp b/src/database/state_delta.hpp
index 8bae866b0..e5f84eba2 100644
--- a/src/database/state_delta.hpp
+++ b/src/database/state_delta.hpp
@@ -10,9 +10,16 @@
 namespace database {
 /** Describes single change to the database state. Used for durability (WAL) and
  * state communication over network in HA and for distributed remote storage
- * changes*/
-class StateDelta {
- public:
+ * changes.
+ *
+ * Labels, Properties and EdgeTypes are stored both as values (integers) and
+ * strings (their names). The values are used when applying deltas in a running
+ * database. Names are used when recovering the database as it's not guaranteed
+ * that after recovery the old name<->value mapping will be preserved.
+ *
+ * TODO: ensure the mapping is preserved after recovery and don't save strings
+ * in StateDeltas. */
+struct StateDelta {
   /** Defines StateDelta type. For each type the comment indicates which values
    * need to be stored. All deltas have the transaction_id member, so that's
    * omitted in the comment. */
@@ -21,20 +28,21 @@ class StateDelta {
     TRANSACTION_COMMIT,
     TRANSACTION_ABORT,
     CREATE_VERTEX,        // vertex_id
-    CREATE_EDGE,          // edge_id, from_vertex_id, to_vertex_id, edge_type
-    SET_PROPERTY_VERTEX,  // vertex_id, property, property_value
-    SET_PROPERTY_EDGE,    // edge_id, property, property_value
+    CREATE_EDGE,          // edge_id, from_vertex_id, to_vertex_id, edge_type,
+                          // edge_type_name
+    SET_PROPERTY_VERTEX,  // vertex_id, property, property_name, property_value
+    SET_PROPERTY_EDGE,    // edge_id, property, property_name, property_value
     // remove property is done by setting a PropertyValue::Null
-    ADD_LABEL,      // vertex_id, label
-    REMOVE_LABEL,   // vertex_id, label
+    ADD_LABEL,      // vertex_id, label, label_name
+    REMOVE_LABEL,   // vertex_id, label, label_name
     REMOVE_VERTEX,  // vertex_id
     REMOVE_EDGE,    // edge_id
-    BUILD_INDEX     // label, property
+    BUILD_INDEX     // label, label_name, property, property_name
   };
 
   StateDelta() = default;
   StateDelta(const enum Type &type, tx::transaction_id_t tx_id)
-      : type_(type), transaction_id_(tx_id) {}
+      : type(type), transaction_id(tx_id) {}
 
   /** Attempts to decode a StateDelta from the given decoder. Returns the
    * decoded value if successful, otherwise returns nullopt. */
@@ -48,9 +56,6 @@ class StateDelta {
       HashedFileWriter &writer,
       communication::bolt::PrimitiveEncoder<HashedFileWriter> &encoder) const;
 
-  tx::transaction_id_t transaction_id() const { return transaction_id_; }
-  Type type() const { return type_; }
-
   static StateDelta TxBegin(tx::transaction_id_t tx_id);
   static StateDelta TxCommit(tx::transaction_id_t tx_id);
   static StateDelta TxAbort(tx::transaction_id_t tx_id);
@@ -58,43 +63,49 @@ class StateDelta {
                                  gid::Gid vertex_id);
   static StateDelta CreateEdge(tx::transaction_id_t tx_id, gid::Gid edge_id,
                                gid::Gid vertex_from_id, gid::Gid vertex_to_id,
-                               const std::string &edge_type);
+                               storage::EdgeType edge_type,
+                               const std::string &edge_type_name);
   static StateDelta PropsSetVertex(tx::transaction_id_t tx_id,
                                    gid::Gid vertex_id,
-                                   const std::string &property,
+                                   storage::Property property,
+                                   const std::string &property_name,
                                    const PropertyValue &value);
   static StateDelta PropsSetEdge(tx::transaction_id_t tx_id, gid::Gid edge_id,
-                                 const std::string &property,
+                                 storage::Property property,
+                                 const std::string &property_name,
                                  const PropertyValue &value);
   static StateDelta AddLabel(tx::transaction_id_t tx_id, gid::Gid vertex_id,
-                             const std::string &label);
+                             storage::Label label,
+                             const std::string &label_name);
   static StateDelta RemoveLabel(tx::transaction_id_t tx_id, gid::Gid vertex_id,
-                                const std::string &label);
+                                storage::Label label,
+                                const std::string &label_name);
   static StateDelta RemoveVertex(tx::transaction_id_t tx_id,
                                  gid::Gid vertex_id);
   static StateDelta RemoveEdge(tx::transaction_id_t tx_id, gid::Gid edge_id);
-  static StateDelta BuildIndex(tx::transaction_id_t tx_id,
-                               const std::string &label,
-                               const std::string &property);
-
-  std::pair<std::string, std::string> IndexName() const;
+  static StateDelta BuildIndex(tx::transaction_id_t tx_id, storage::Label label,
+                               const std::string &label_name,
+                               storage::Property property,
+                               const std::string &property_name);
 
   /// Applies CRUD delta to database accessor. Fails on other types of deltas
   void Apply(GraphDbAccessor &dba) const;
 
- private:
   // Members valid for every delta.
-  enum Type type_;
-  tx::transaction_id_t transaction_id_;
+  enum Type type;
+  tx::transaction_id_t transaction_id;
 
   // Members valid only for some deltas, see StateDelta::Type comments above.
-  gid::Gid vertex_id_;
-  gid::Gid edge_id_;
-  gid::Gid vertex_from_id_;
-  gid::Gid vertex_to_id_;
-  std::string edge_type_;
-  std::string property_;
-  PropertyValue value_ = PropertyValue::Null;
-  std::string label_;
+  gid::Gid vertex_id;
+  gid::Gid edge_id;
+  gid::Gid vertex_from_id;
+  gid::Gid vertex_to_id;
+  storage::EdgeType edge_type;
+  std::string edge_type_name;
+  storage::Property property;
+  std::string property_name;
+  PropertyValue value = PropertyValue::Null;
+  storage::Label label;
+  std::string label_name;
 };
 }  // namespace database
diff --git a/src/durability/recovery.cpp b/src/durability/recovery.cpp
index 43f42d9bd..7172770f7 100644
--- a/src/durability/recovery.cpp
+++ b/src/durability/recovery.cpp
@@ -272,27 +272,28 @@ bool RecoverWal(const fs::path &wal_dir, database::GraphDb &db,
     while (true) {
       auto delta = database::StateDelta::Decode(wal_reader, decoder);
       if (!delta) break;
-      if (should_skip(delta->transaction_id())) continue;
-      switch (delta->type()) {
+      if (should_skip(delta->transaction_id)) continue;
+      switch (delta->type) {
         case database::StateDelta::Type::TRANSACTION_BEGIN:
-          DCHECK(accessors.find(delta->transaction_id()) == accessors.end())
+          DCHECK(accessors.find(delta->transaction_id) == accessors.end())
               << "Double transaction start";
-          accessors.emplace(delta->transaction_id(), db);
+          accessors.emplace(delta->transaction_id, db);
           break;
         case database::StateDelta::Type::TRANSACTION_ABORT:
-          get_accessor(delta->transaction_id()).Abort();
-          accessors.erase(accessors.find(delta->transaction_id()));
+          get_accessor(delta->transaction_id).Abort();
+          accessors.erase(accessors.find(delta->transaction_id));
           break;
         case database::StateDelta::Type::TRANSACTION_COMMIT:
-          get_accessor(delta->transaction_id()).Commit();
-          accessors.erase(accessors.find(delta->transaction_id()));
+          get_accessor(delta->transaction_id).Commit();
+          accessors.erase(accessors.find(delta->transaction_id));
           break;
         case database::StateDelta::Type::BUILD_INDEX:
           // TODO index building might still be problematic in HA
-          recovery_data.indexes.emplace_back(delta->IndexName());
+          recovery_data.indexes.emplace_back(delta->label_name,
+                                             delta->property_name);
           break;
         default:
-          delta->Apply(get_accessor(delta->transaction_id()));
+          delta->Apply(get_accessor(delta->transaction_id));
       }
     }  // reading all deltas in a single wal file
   }    // reading all wal files
diff --git a/src/durability/wal.cpp b/src/durability/wal.cpp
index 4c7b67e7e..dea4e2166 100644
--- a/src/durability/wal.cpp
+++ b/src/durability/wal.cpp
@@ -74,7 +74,7 @@ void WriteAheadLog::WalFile::Flush(RingBuffer<database::StateDelta> &buffer) {
     while (true) {
       auto delta = buffer.pop();
       if (!delta) break;
-      latest_tx_ = std::max(latest_tx_, delta->transaction_id());
+      latest_tx_ = std::max(latest_tx_, delta->transaction_id);
       delta->Encode(writer_, encoder_);
       if (++current_wal_file_delta_count_ >= FLAGS_wal_rotate_deltas_count)
         RotateFile();
diff --git a/src/storage/record_accessor.cpp b/src/storage/record_accessor.cpp
index 4cc38bb9f..9b2859a4e 100644
--- a/src/storage/record_accessor.cpp
+++ b/src/storage/record_accessor.cpp
@@ -25,7 +25,7 @@ void RecordAccessor<Vertex>::PropsSet(storage::Property key,
   vertex.properties_.set(key, value);
   auto &dba = db_accessor();
   // TODO use the delta for handling.
-  dba.wal().Emplace(StateDelta::PropsSetVertex(dba.transaction_id(), gid(),
+  dba.wal().Emplace(StateDelta::PropsSetVertex(dba.transaction_id(), gid(), key,
                                                dba.PropertyName(key), value));
   if (is_local()) {
     db_accessor().UpdatePropertyIndex(key, *this, &vertex);
@@ -38,7 +38,7 @@ void RecordAccessor<Edge>::PropsSet(storage::Property key,
   update().properties_.set(key, value);
   auto &dba = db_accessor();
   // TODO use the delta for handling.
-  dba.wal().Emplace(StateDelta::PropsSetEdge(dba.transaction_id(), gid(),
+  dba.wal().Emplace(StateDelta::PropsSetEdge(dba.transaction_id(), gid(), key,
                                              dba.PropertyName(key), value));
 }
 
@@ -46,8 +46,9 @@ template <>
 size_t RecordAccessor<Vertex>::PropsErase(storage::Property key) {
   auto &dba = db_accessor();
   // TODO use the delta for handling.
-  dba.wal().Emplace(StateDelta::PropsSetVertex(
-      dba.transaction_id(), gid(), dba.PropertyName(key), PropertyValue::Null));
+  dba.wal().Emplace(StateDelta::PropsSetVertex(dba.transaction_id(), gid(), key,
+                                               dba.PropertyName(key),
+                                               PropertyValue::Null));
   return update().properties_.erase(key);
 }
 
@@ -55,8 +56,9 @@ template <>
 size_t RecordAccessor<Edge>::PropsErase(storage::Property key) {
   auto &dba = db_accessor();
   // TODO use the delta for handling.
-  dba.wal().Emplace(StateDelta::PropsSetEdge(
-      dba.transaction_id(), gid(), dba.PropertyName(key), PropertyValue::Null));
+  dba.wal().Emplace(StateDelta::PropsSetEdge(dba.transaction_id(), gid(), key,
+                                             dba.PropertyName(key),
+                                             PropertyValue::Null));
   return update().properties_.erase(key);
 }
 
@@ -66,9 +68,9 @@ void RecordAccessor<Vertex>::PropsClear() {
   // TODO use the delta for handling.
   auto &dba = db_accessor();
   for (const auto &kv : updated.properties_)
-    dba.wal().Emplace(StateDelta::PropsSetVertex(dba.transaction_id(), gid(),
-                                                 dba.PropertyName(kv.first),
-                                                 PropertyValue::Null));
+    dba.wal().Emplace(StateDelta::PropsSetVertex(
+        dba.transaction_id(), gid(), kv.first, dba.PropertyName(kv.first),
+        PropertyValue::Null));
   updated.properties_.clear();
 }
 
@@ -78,9 +80,9 @@ void RecordAccessor<Edge>::PropsClear() {
   auto &dba = db_accessor();
   // TODO use the delta for handling.
   for (const auto &kv : updated.properties_)
-    dba.wal().Emplace(StateDelta::PropsSetEdge(dba.transaction_id(), gid(),
-                                               dba.PropertyName(kv.first),
-                                               PropertyValue::Null));
+    dba.wal().Emplace(StateDelta::PropsSetEdge(
+        dba.transaction_id(), gid(), kv.first, dba.PropertyName(kv.first),
+        PropertyValue::Null));
   updated.properties_.clear();
 }
 
diff --git a/src/storage/vertex_accessor.cpp b/src/storage/vertex_accessor.cpp
index c155d078c..0a5c84381 100644
--- a/src/storage/vertex_accessor.cpp
+++ b/src/storage/vertex_accessor.cpp
@@ -20,8 +20,8 @@ bool VertexAccessor::add_label(storage::Label label) {
   auto &dba = db_accessor();
   dba.UpdateLabelIndices(label, *this, &vertex);
   // TODO support distributed.
-  dba.wal().Emplace(database::StateDelta::AddLabel(dba.transaction_id(), gid(),
-                                                   dba.LabelName(label)));
+  dba.wal().Emplace(database::StateDelta::AddLabel(
+      dba.transaction_id(), gid(), label, dba.LabelName(label)));
   return true;
 }
 
@@ -35,7 +35,7 @@ size_t VertexAccessor::remove_label(storage::Label label) {
   auto &dba = db_accessor();
   // TODO support distributed.
   dba.wal().Emplace(database::StateDelta::RemoveLabel(
-      dba.transaction_id(), gid(), dba.LabelName(label)));
+      dba.transaction_id(), gid(), label, dba.LabelName(label)));
   return 1;
 }
 
diff --git a/tests/unit/durability.cpp b/tests/unit/durability.cpp
index 055787122..83433a641 100644
--- a/tests/unit/durability.cpp
+++ b/tests/unit/durability.cpp
@@ -357,29 +357,28 @@ TEST_F(Durability, WalEncoding) {
   ASSERT_EQ(deltas.size(), 11);
 
   using Type = enum database::StateDelta::Type;
-  EXPECT_EQ(deltas[0].type(), Type::TRANSACTION_BEGIN);
-  EXPECT_EQ(deltas[0].transaction_id(), 1);
-  EXPECT_EQ(deltas[1].type(), Type::CREATE_VERTEX);
-  EXPECT_EQ(deltas[1].transaction_id(), 1);
-  EXPECT_EQ(deltas[2].type(), Type::ADD_LABEL);
-  EXPECT_EQ(deltas[2].transaction_id(), 1);
-  EXPECT_EQ(deltas[3].type(), Type::SET_PROPERTY_VERTEX);
-  EXPECT_EQ(deltas[3].transaction_id(), 1);
-  EXPECT_EQ(deltas[4].type(), Type::CREATE_VERTEX);
-  EXPECT_EQ(deltas[4].transaction_id(), 1);
-  EXPECT_EQ(deltas[5].type(), Type::CREATE_EDGE);
-  EXPECT_EQ(deltas[5].transaction_id(), 1);
-  EXPECT_EQ(deltas[6].type(), Type::SET_PROPERTY_EDGE);
-  EXPECT_EQ(deltas[6].transaction_id(), 1);
+  EXPECT_EQ(deltas[0].type, Type::TRANSACTION_BEGIN);
+  EXPECT_EQ(deltas[0].transaction_id, 1);
+  EXPECT_EQ(deltas[1].type, Type::CREATE_VERTEX);
+  EXPECT_EQ(deltas[1].transaction_id, 1);
+  EXPECT_EQ(deltas[2].type, Type::ADD_LABEL);
+  EXPECT_EQ(deltas[2].transaction_id, 1);
+  EXPECT_EQ(deltas[3].type, Type::SET_PROPERTY_VERTEX);
+  EXPECT_EQ(deltas[3].transaction_id, 1);
+  EXPECT_EQ(deltas[4].type, Type::CREATE_VERTEX);
+  EXPECT_EQ(deltas[4].transaction_id, 1);
+  EXPECT_EQ(deltas[5].type, Type::CREATE_EDGE);
+  EXPECT_EQ(deltas[5].transaction_id, 1);
+  EXPECT_EQ(deltas[6].type, Type::SET_PROPERTY_EDGE);
+  EXPECT_EQ(deltas[6].transaction_id, 1);
   // The next two deltas are the BuildIndex internal transactions.
-  EXPECT_EQ(deltas[7].type(), Type::TRANSACTION_BEGIN);
-  EXPECT_EQ(deltas[8].type(), Type::BUILD_INDEX);
-  auto index_name = deltas[8].IndexName();
-  EXPECT_EQ(index_name.first, "l1");
-  EXPECT_EQ(index_name.second, "p1");
-  EXPECT_EQ(deltas[9].type(), Type::TRANSACTION_COMMIT);
-  EXPECT_EQ(deltas[10].type(), Type::TRANSACTION_COMMIT);
-  EXPECT_EQ(deltas[10].transaction_id(), 1);
+  EXPECT_EQ(deltas[7].type, Type::TRANSACTION_BEGIN);
+  EXPECT_EQ(deltas[8].type, Type::BUILD_INDEX);
+  EXPECT_EQ(deltas[8].label_name, "l1");
+  EXPECT_EQ(deltas[8].property_name, "p1");
+  EXPECT_EQ(deltas[9].type, Type::TRANSACTION_COMMIT);
+  EXPECT_EQ(deltas[10].type, Type::TRANSACTION_COMMIT);
+  EXPECT_EQ(deltas[10].transaction_id, 1);
 }
 
 TEST_F(Durability, SnapshotEncoding) {
diff --git a/tests/unit/state_delta.cpp b/tests/unit/state_delta.cpp
index e84708c55..059b05564 100644
--- a/tests/unit/state_delta.cpp
+++ b/tests/unit/state_delta.cpp
@@ -57,8 +57,8 @@ TEST(StateDelta, CreateEdge) {
   }
   {
     database::GraphDbAccessor dba(db);
-    auto delta = database::StateDelta::CreateEdge(dba.transaction_id(), gid2,
-                                                  gid0, gid1, "edge");
+    auto delta = database::StateDelta::CreateEdge(
+        dba.transaction_id(), gid2, gid0, gid1, dba.EdgeType("edge"), "edge");
     delta.Apply(dba);
     dba.Commit();
   }
@@ -106,8 +106,8 @@ TEST(StateDelta, AddLabel) {
   }
   {
     database::GraphDbAccessor dba(db);
-    auto delta =
-        database::StateDelta::AddLabel(dba.transaction_id(), gid0, "label");
+    auto delta = database::StateDelta::AddLabel(dba.transaction_id(), gid0,
+                                                dba.Label("label"), "label");
     delta.Apply(dba);
     dba.Commit();
   }
@@ -133,8 +133,8 @@ TEST(StateDelta, RemoveLabel) {
   }
   {
     database::GraphDbAccessor dba(db);
-    auto delta =
-        database::StateDelta::RemoveLabel(dba.transaction_id(), gid0, "label");
+    auto delta = database::StateDelta::RemoveLabel(dba.transaction_id(), gid0,
+                                                   dba.Label("label"), "label");
     delta.Apply(dba);
     dba.Commit();
   }
@@ -159,7 +159,8 @@ TEST(StateDelta, SetPropertyVertex) {
   {
     database::GraphDbAccessor dba(db);
     auto delta = database::StateDelta::PropsSetVertex(
-        dba.transaction_id(), gid0, "property", PropertyValue(2212));
+        dba.transaction_id(), gid0, dba.Property("property"), "property",
+        PropertyValue(2212));
     delta.Apply(dba);
     dba.Commit();
   }
@@ -188,7 +189,8 @@ TEST(StateDelta, SetPropertyEdge) {
   {
     database::GraphDbAccessor dba(db);
     auto delta = database::StateDelta::PropsSetEdge(
-        dba.transaction_id(), gid2, "property", PropertyValue(2212));
+        dba.transaction_id(), gid2, dba.Property("property"), "property",
+        PropertyValue(2212));
     delta.Apply(dba);
     dba.Commit();
   }