diff --git a/src/storage/v2/constraints/existence_constraints.cpp b/src/storage/v2/constraints/existence_constraints.cpp
index 692dddbb6..a0d303c03 100644
--- a/src/storage/v2/constraints/existence_constraints.cpp
+++ b/src/storage/v2/constraints/existence_constraints.cpp
@@ -51,7 +51,7 @@ std::vector<std::pair<LabelId, PropertyId>> ExistenceConstraints::ListConstraint
 void ExistenceConstraints::LoadExistenceConstraints(const std::vector<std::string> &keys) {
   for (const auto &key : keys) {
     const std::vector<std::string> parts = utils::Split(key, ",");
-    constraints_.emplace_back(LabelId::FromUint(std::stoull(parts[0])), PropertyId::FromUint(std::stoull(parts[1])));
+    constraints_.emplace_back(LabelId::FromString(parts[0]), PropertyId::FromString(parts[1]));
   }
 }
 
diff --git a/src/storage/v2/disk/label_index.cpp b/src/storage/v2/disk/label_index.cpp
index a8036ec33..3ca7cd353 100644
--- a/src/storage/v2/disk/label_index.cpp
+++ b/src/storage/v2/disk/label_index.cpp
@@ -208,7 +208,7 @@ uint64_t DiskLabelIndex::ApproximateVertexCount(LabelId /*label*/) const { retur
 
 void DiskLabelIndex::LoadIndexInfo(const std::vector<std::string> &labels) {
   for (const std::string &label : labels) {
-    LabelId label_id = LabelId::FromUint(std::stoull(label));
+    LabelId label_id = LabelId::FromString(label);
     index_.insert(label_id);
   }
 }
diff --git a/src/storage/v2/disk/label_property_index.cpp b/src/storage/v2/disk/label_property_index.cpp
index 5c7f0f05d..7e82ed36d 100644
--- a/src/storage/v2/disk/label_property_index.cpp
+++ b/src/storage/v2/disk/label_property_index.cpp
@@ -216,8 +216,8 @@ uint64_t DiskLabelPropertyIndex::ApproximateVertexCount(
 void DiskLabelPropertyIndex::LoadIndexInfo(const std::vector<std::string> &keys) {
   for (const auto &label_property : keys) {
     std::vector<std::string> label_property_split = utils::Split(label_property, ",");
-    index_.emplace(std::make_pair(LabelId::FromUint(std::stoull(label_property_split[0])),
-                                  PropertyId::FromUint(std::stoull(label_property_split[1]))));
+    index_.emplace(
+        std::make_pair(LabelId::FromString(label_property_split[0]), PropertyId::FromString(label_property_split[1])));
   }
 }
 
diff --git a/src/storage/v2/disk/name_id_mapper.hpp b/src/storage/v2/disk/name_id_mapper.hpp
index 89d23993c..bd2165c6a 100644
--- a/src/storage/v2/disk/name_id_mapper.hpp
+++ b/src/storage/v2/disk/name_id_mapper.hpp
@@ -12,6 +12,7 @@
 #pragma once
 
 #include <atomic>
+#include <charconv>
 #include <cstddef>
 #include <filesystem>
 #include <memory>
@@ -43,7 +44,8 @@ class DiskNameIdMapper final : public NameIdMapper {
     }
     uint64_t res_id = 0;
     if (auto maybe_id_from_disk = name_to_id_storage_->Get(std::string(name)); maybe_id_from_disk.has_value()) {
-      res_id = std::stoull(maybe_id_from_disk.value());
+      auto id_disk_value = maybe_id_from_disk.value();
+      res_id = utils::ParseStringToUint64(id_disk_value);
       InsertNameIdEntryToCache(std::string(name), res_id);
       InsertIdNameEntryToCache(res_id, std::string(name));
     } else {
@@ -92,14 +94,14 @@ class DiskNameIdMapper final : public NameIdMapper {
 
   void InitializeFromDisk() {
     for (auto itr = name_to_id_storage_->begin(); itr != name_to_id_storage_->end(); ++itr) {
-      auto name = itr->first;
-      auto id = std::stoull(itr->second);
+      std::string name = itr->first;
+      uint64_t id = utils::ParseStringToUint64(itr->second);
       InsertNameIdEntryToCache(name, id);
       counter_.fetch_add(1, std::memory_order_release);
     }
     for (auto itr = id_to_name_storage_->begin(); itr != id_to_name_storage_->end(); ++itr) {
-      auto id = std::stoull(itr->first);
-      auto name = itr->second;
+      uint64_t id = utils::ParseStringToUint64(itr->first);
+      std::string name = itr->second;
       InsertIdNameEntryToCache(id, name);
     }
   }
diff --git a/src/storage/v2/disk/storage.cpp b/src/storage/v2/disk/storage.cpp
index fdd4f3e1b..ff3fe0ebf 100644
--- a/src/storage/v2/disk/storage.cpp
+++ b/src/storage/v2/disk/storage.cpp
@@ -10,6 +10,7 @@
 // licenses/APL.txt.
 
 #include <atomic>
+#include <charconv>
 #include <cstdint>
 #include <limits>
 #include <optional>
@@ -203,7 +204,8 @@ void DiskStorage::LoadTimestampIfExists() {
     return;
   }
   if (auto last_timestamp_ = durability_kvstore_->Get(lastTransactionStartTimeStamp); last_timestamp_.has_value()) {
-    timestamp_ = std::stoull(last_timestamp_.value());
+    auto last_timestamp_value = last_timestamp_.value();
+    std::from_chars(last_timestamp_value.data(), last_timestamp_value.data() + last_timestamp_value.size(), timestamp_);
   }
 }
 
@@ -348,7 +350,7 @@ std::optional<storage::VertexAccessor> DiskStorage::DiskAccessor::LoadVertexToMa
                                                                                               std::string &&ts) {
   auto main_storage_accessor = vertices_.access();
 
-  storage::Gid gid = Gid::FromUint(std::stoull(utils::ExtractGidFromKey(key)));
+  storage::Gid gid = Gid::FromString(utils::ExtractGidFromKey(key));
   if (ObjectExistsInCache(main_storage_accessor, gid)) {
     return std::nullopt;
   }
@@ -361,7 +363,7 @@ std::optional<storage::VertexAccessor> DiskStorage::DiskAccessor::LoadVertexToMa
 std::optional<storage::VertexAccessor> DiskStorage::DiskAccessor::LoadVertexToLabelIndexCache(
     std::string &&key, std::string &&value, Delta *index_delta,
     utils::SkipList<storage::Vertex>::Accessor index_accessor) {
-  storage::Gid gid = Gid::FromUint(std::stoull(utils::ExtractGidFromLabelIndexStorage(key)));
+  storage::Gid gid = Gid::FromString(utils::ExtractGidFromLabelIndexStorage(key));
   if (ObjectExistsInCache(index_accessor, gid)) {
     return std::nullopt;
   }
@@ -374,7 +376,7 @@ std::optional<storage::VertexAccessor> DiskStorage::DiskAccessor::LoadVertexToLa
 std::optional<storage::VertexAccessor> DiskStorage::DiskAccessor::LoadVertexToLabelPropertyIndexCache(
     std::string &&key, std::string &&value, Delta *index_delta,
     utils::SkipList<storage::Vertex>::Accessor index_accessor) {
-  storage::Gid gid = Gid::FromUint(std::stoull(utils::ExtractGidFromLabelPropertyIndexStorage(key)));
+  storage::Gid gid = Gid::FromString(utils::ExtractGidFromLabelPropertyIndexStorage(key));
   if (ObjectExistsInCache(index_accessor, gid)) {
     return std::nullopt;
   }
@@ -387,7 +389,7 @@ std::optional<EdgeAccessor> DiskStorage::DiskAccessor::DeserializeEdge(const roc
                                                                        const rocksdb::Slice &value,
                                                                        const rocksdb::Slice &ts) {
   const auto edge_parts = utils::Split(key.ToStringView(), "|");
-  const Gid edge_gid = Gid::FromUint(std::stoull(edge_parts[4]));
+  const Gid edge_gid = Gid::FromString(edge_parts[4]);
 
   auto edge_acc = edges_.access();
   auto res = edge_acc.find(edge_gid);
@@ -405,12 +407,12 @@ std::optional<EdgeAccessor> DiskStorage::DiskAccessor::DeserializeEdge(const roc
       },
       edge_parts);
 
-  const auto from_acc = FindVertex(Gid::FromUint(std::stoull(from_gid)), View::OLD);
-  const auto to_acc = FindVertex(Gid::FromUint(std::stoull(to_gid)), View::OLD);
+  const auto from_acc = FindVertex(Gid::FromString(from_gid), View::OLD);
+  const auto to_acc = FindVertex(Gid::FromString(to_gid), View::OLD);
   if (!from_acc || !to_acc) {
     throw utils::BasicException("Non-existing vertices found during edge deserialization");
   }
-  const auto edge_type_id = storage::EdgeTypeId::FromUint(std::stoull(edge_parts[3]));
+  const auto edge_type_id = storage::EdgeTypeId::FromString(edge_parts[3]);
   auto maybe_edge = CreateEdgeFromDisk(&*from_acc, &*to_acc, edge_type_id, edge_gid, value.ToStringView(),
                                        key.ToString(), ts.ToString());
   MG_ASSERT(maybe_edge.HasValue());
@@ -450,7 +452,7 @@ void DiskStorage::DiskAccessor::LoadVerticesFromMainStorageToEdgeImportCache() {
   for (it->SeekToFirst(); it->Valid(); it->Next()) {
     std::string key = it->key().ToString();
     std::string value = it->value().ToString();
-    storage::Gid gid = Gid::FromUint(std::stoull(utils::ExtractGidFromMainDiskStorage(key)));
+    storage::Gid gid = Gid::FromString(utils::ExtractGidFromMainDiskStorage(key));
     if (ObjectExistsInCache(cache_accessor, gid)) continue;
 
     std::vector<LabelId> labels_id{utils::DeserializeLabelsFromMainDiskStorage(key)};
@@ -485,7 +487,7 @@ void DiskStorage::DiskAccessor::LoadVerticesFromLabelIndexStorageToEdgeImportCac
     std::string key = it->key().ToString();
     std::string value = it->value().ToString();
     if (key.starts_with(label_prefix)) {
-      storage::Gid gid = Gid::FromUint(std::stoull(utils::ExtractGidFromLabelIndexStorage(key)));
+      storage::Gid gid = Gid::FromString(utils::ExtractGidFromLabelIndexStorage(key));
       if (ObjectExistsInCache(cache_accessor, gid)) continue;
 
       std::vector<LabelId> labels_id{utils::DeserializeLabelsFromLabelIndexStorage(key, value)};
@@ -539,7 +541,7 @@ void DiskStorage::DiskAccessor::LoadVerticesFromLabelPropertyIndexStorageToEdgeI
     std::string key = it->key().ToString();
     std::string value = it->value().ToString();
     if (key.starts_with(label_property_prefix)) {
-      storage::Gid gid = Gid::FromUint(std::stoull(utils::ExtractGidFromLabelPropertyIndexStorage(key)));
+      storage::Gid gid = Gid::FromString(utils::ExtractGidFromLabelPropertyIndexStorage(key));
       if (ObjectExistsInCache(cache_accessor, gid)) continue;
 
       std::vector<LabelId> labels_id{utils::DeserializeLabelsFromLabelPropertyIndexStorage(key, value)};
@@ -726,7 +728,7 @@ void DiskStorage::DiskAccessor::LoadVerticesFromDiskLabelIndex(LabelId label,
   const auto serialized_label = utils::SerializeIdType(label);
   for (index_it->SeekToFirst(); index_it->Valid(); index_it->Next()) {
     std::string key = index_it->key().ToString();
-    Gid curr_gid = Gid::FromUint(std::stoull(utils::ExtractGidFromLabelIndexStorage(key)));
+    Gid curr_gid = Gid::FromString(utils::ExtractGidFromLabelIndexStorage(key));
     spdlog::trace("Loaded vertex with key: {} from label index storage", key);
     if (key.starts_with(serialized_label) && !utils::Contains(gids, curr_gid)) {
       // We should pass it->timestamp().ToString() instead of "0"
@@ -780,7 +782,7 @@ void DiskStorage::DiskAccessor::LoadVerticesFromDiskLabelPropertyIndex(LabelId l
   const auto label_property_prefix = utils::SerializeIdType(label) + "|" + utils::SerializeIdType(property);
   for (index_it->SeekToFirst(); index_it->Valid(); index_it->Next()) {
     std::string key = index_it->key().ToString();
-    Gid curr_gid = Gid::FromUint(std::stoull(utils::ExtractGidFromLabelPropertyIndexStorage(key)));
+    Gid curr_gid = Gid::FromString(utils::ExtractGidFromLabelPropertyIndexStorage(key));
     /// TODO: optimize
     if (label_property_filter(key, label_property_prefix, gids, curr_gid)) {
       // We should pass it->timestamp().ToString() instead of "0"
@@ -810,7 +812,7 @@ void DiskStorage::DiskAccessor::LoadVerticesFromDiskLabelPropertyIndexWithPointV
   for (index_it->SeekToFirst(); index_it->Valid(); index_it->Next()) {
     std::string key = index_it->key().ToString();
     std::string it_value = index_it->value().ToString();
-    Gid curr_gid = Gid::FromUint(std::stoull(utils::ExtractGidFromLabelPropertyIndexStorage(key)));
+    Gid curr_gid = Gid::FromString(utils::ExtractGidFromLabelPropertyIndexStorage(key));
     /// TODO: optimize
     PropertyStore properties = utils::DeserializePropertiesFromLabelPropertyIndexStorage(it_value);
     if (key.starts_with(label_property_prefix) && !utils::Contains(gids, curr_gid) &&
@@ -869,7 +871,7 @@ void DiskStorage::DiskAccessor::LoadVerticesFromDiskLabelPropertyIndexForInterva
   for (index_it->SeekToFirst(); index_it->Valid(); index_it->Next()) {
     std::string key_str = index_it->key().ToString();
     std::string it_value_str = index_it->value().ToString();
-    Gid curr_gid = Gid::FromUint(std::stoull(utils::ExtractGidFromLabelPropertyIndexStorage(key_str)));
+    Gid curr_gid = Gid::FromString(utils::ExtractGidFromLabelPropertyIndexStorage(key_str));
     /// TODO: andi this will be optimized
     /// TODO: couple this condition
     PropertyStore properties = utils::DeserializePropertiesFromLabelPropertyIndexStorage(it_value_str);
@@ -1076,7 +1078,7 @@ std::optional<VertexAccessor> DiskStorage::DiskAccessor::FindVertex(storage::Gid
       disk_transaction_->GetIterator(read_opts, disk_storage->kvstore_->vertex_chandle));
   for (it->SeekToFirst(); it->Valid(); it->Next()) {
     std::string key = it->key().ToString();
-    if (Gid::FromUint(std::stoull(utils::ExtractGidFromKey(key))) == gid) {
+    if (Gid::FromString(utils::ExtractGidFromKey(key)) == gid) {
       // We should pass it->timestamp().ToString() instead of "0"
       // This is hack until RocksDB will support timestamp() in WBWI iterator
       return LoadVertexToMainMemoryCache(std::move(key), it->value().ToString(), deserializeTimestamp);
diff --git a/src/storage/v2/disk/unique_constraints.cpp b/src/storage/v2/disk/unique_constraints.cpp
index cf0583281..9519e4357 100644
--- a/src/storage/v2/disk/unique_constraints.cpp
+++ b/src/storage/v2/disk/unique_constraints.cpp
@@ -340,10 +340,10 @@ RocksDBStorage *DiskUniqueConstraints::GetRocksDBStorage() const { return kvstor
 void DiskUniqueConstraints::LoadUniqueConstraints(const std::vector<std::string> &keys) {
   for (const auto &key : keys) {
     std::vector<std::string> key_parts = utils::Split(key, ",");
-    LabelId label = LabelId::FromUint(std::stoull(key_parts[0]));
+    LabelId label = LabelId::FromString(key_parts[0]);
     std::set<PropertyId> properties;
     for (int i = 1; i < key_parts.size(); i++) {
-      properties.insert(PropertyId::FromUint(std::stoull(key_parts[i])));
+      properties.insert(PropertyId::FromString(key_parts[i]));
     }
     constraints_.emplace(std::make_pair(label, properties));
   }
diff --git a/src/storage/v2/id_types.hpp b/src/storage/v2/id_types.hpp
index 0a954985e..7579e4b66 100644
--- a/src/storage/v2/id_types.hpp
+++ b/src/storage/v2/id_types.hpp
@@ -1,4 +1,4 @@
-// Copyright 2022 Memgraph Ltd.
+// Copyright 2023 Memgraph Ltd.
 //
 // Use of this software is governed by the Business Source License
 // included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
@@ -11,10 +11,14 @@
 
 #pragma once
 
+#include <charconv>
 #include <functional>
+#include <system_error>
 #include <type_traits>
+#include <utils/exceptions.hpp>
 
 #include "utils/cast.hpp"
+#include "utils/string.hpp"
 
 namespace memgraph::storage {
 
@@ -31,6 +35,7 @@ namespace memgraph::storage {
     static name FromInt(int64_t id) { return name{utils::MemcpyCast<uint64_t>(id)}; }                         \
     uint64_t AsUint() const { return id_; }                                                                   \
     int64_t AsInt() const { return utils::MemcpyCast<int64_t>(id_); }                                         \
+    static name FromString(std::string_view id) { return name{utils::ParseStringToUint64(id)}; }              \
                                                                                                               \
    private:                                                                                                   \
     uint64_t id_;                                                                                             \
diff --git a/src/storage/v2/mvcc.hpp b/src/storage/v2/mvcc.hpp
index 2be20f803..f046a9b01 100644
--- a/src/storage/v2/mvcc.hpp
+++ b/src/storage/v2/mvcc.hpp
@@ -19,6 +19,7 @@
 #include "storage/v2/transaction.hpp"
 #include "storage/v2/view.hpp"
 #include "utils/rocksdb_serialization.hpp"
+#include "utils/string.hpp"
 
 namespace memgraph::storage {
 
@@ -131,13 +132,15 @@ inline Delta *CreateDeleteDeserializedObjectDelta(Transaction *transaction, std:
                                                   std::string &&ts) {
   transaction->EnsureCommitTimestampExists();
   // Should use utils::DecodeFixed64(ts.c_str()) once we will move to RocksDB real timestamps
-  return &transaction->deltas.use().emplace_back(Delta::DeleteDeserializedObjectTag(), std::stoull(ts), old_disk_key);
+  uint64_t ts_id = utils::ParseStringToUint64(ts);
+  return &transaction->deltas.use().emplace_back(Delta::DeleteDeserializedObjectTag(), ts_id, old_disk_key);
 }
 
 inline Delta *CreateDeleteDeserializedObjectDelta(std::list<Delta> *deltas, std::optional<std::string> old_disk_key,
                                                   std::string &&ts) {
   // Should use utils::DecodeFixed64(ts.c_str()) once we will move to RocksDB real timestamps
-  return &deltas->emplace_back(Delta::DeleteDeserializedObjectTag(), std::stoull(ts), old_disk_key);
+  uint64_t ts_id = utils::ParseStringToUint64(ts);
+  return &deltas->emplace_back(Delta::DeleteDeserializedObjectTag(), ts_id, old_disk_key);
 }
 
 inline Delta *CreateDeleteDeserializedIndexObjectDelta(std::list<Delta> &deltas,
@@ -149,7 +152,8 @@ inline Delta *CreateDeleteDeserializedIndexObjectDelta(std::list<Delta> &deltas,
 inline Delta *CreateDeleteDeserializedIndexObjectDelta(std::list<Delta> &deltas,
                                                        std::optional<std::string> old_disk_key, const std::string &ts) {
   // Should use utils::DecodeFixed64(ts.c_str()) once we will move to RocksDB real timestamps
-  return CreateDeleteDeserializedIndexObjectDelta(deltas, old_disk_key, std::stoull(ts));
+  uint64_t ts_id = utils::ParseStringToUint64(ts);
+  return CreateDeleteDeserializedIndexObjectDelta(deltas, old_disk_key, ts_id);
 }
 
 /// This function creates a delta in the transaction for the object and links
diff --git a/src/utils/exceptions.hpp b/src/utils/exceptions.hpp
index f89aa037b..3e394a246 100644
--- a/src/utils/exceptions.hpp
+++ b/src/utils/exceptions.hpp
@@ -148,4 +148,14 @@ class NotYetImplemented final : public BasicException {
       : NotYetImplemented(fmt::format(fmt, std::forward<Args>(args)...)) {}
 };
 
+class ParseException final : public BasicException {
+ public:
+  explicit ParseException(const std::string_view what) noexcept
+      : BasicException("Parsing failed for string: " + std::string(what)) {}
+
+  template <class... Args>
+  explicit ParseException(fmt::format_string<Args...> fmt, Args &&...args) noexcept
+      : ParseException(fmt::format(fmt, std::forward<Args>(args)...)) {}
+};
+
 }  // namespace memgraph::utils
diff --git a/src/utils/rocksdb_serialization.hpp b/src/utils/rocksdb_serialization.hpp
index e6da9cfe2..86e629f7d 100644
--- a/src/utils/rocksdb_serialization.hpp
+++ b/src/utils/rocksdb_serialization.hpp
@@ -97,7 +97,7 @@ inline std::vector<storage::LabelId> TransformFromStringLabels(std::vector<std::
   std::vector<storage::LabelId> transformed_labels;
   transformed_labels.reserve(labels.size());
   for (const std::string &label : labels) {
-    transformed_labels.emplace_back(storage::LabelId::FromUint(std::stoull(label)));
+    transformed_labels.emplace_back(storage::LabelId::FromString(label));
   }
   return transformed_labels;
 }
@@ -242,7 +242,7 @@ inline std::vector<storage::LabelId> DeserializeLabelsFromIndexStorage(const std
   std::string labels_str{GetViewOfFirstPartOfSplit(value, '|')};
   std::vector<storage::LabelId> labels{TransformFromStringLabels(utils::Split(labels_str, ","))};
   std::string indexing_label = key.substr(0, key.find('|'));
-  labels.emplace_back(storage::LabelId::FromUint(std::stoull(indexing_label)));
+  labels.emplace_back(storage::LabelId::FromString(indexing_label));
   return labels;
 }
 
diff --git a/src/utils/string.hpp b/src/utils/string.hpp
index 019086b30..833c158c8 100644
--- a/src/utils/string.hpp
+++ b/src/utils/string.hpp
@@ -14,6 +14,8 @@
 
 #include <algorithm>
 #include <cctype>
+#include <charconv>
+#include <cstdint>
 #include <cstring>
 #include <iostream>
 #include <iterator>
@@ -328,6 +330,13 @@ inline int64_t ParseInt(const std::string_view s) {
   return t;
 }
 
+inline uint64_t ParseStringToUint64(const std::string_view s) {
+  if (uint64_t value = 0; std::from_chars(s.data(), s.data() + s.size(), value).ec == std::errc{}) {
+    return value;
+  }
+  throw utils::ParseException(s);
+}
+
 /**
  * Parse a double floating point value from a string using classic locale.
  * Note, the current implementation copies the given string which may perform a