diff --git a/include/opendht/dht_proxy_server.h b/include/opendht/dht_proxy_server.h
index 1a82efa824a2b4f5329953c2b93249734afa6367..b87c47b4c872decc9d7db8b062d179832841bd9d 100644
--- a/include/opendht/dht_proxy_server.h
+++ b/include/opendht/dht_proxy_server.h
@@ -150,22 +150,22 @@ public:
         std::shared_ptr<NodeInfo> nodeInfo {};
 
         std::string toString() const {
-            std::ostringstream ss;
-            ss << "Listens: " << listenCount << " Puts: " << putCount << " PushListeners: " << pushListenersCount << std::endl;
-            ss << "Push requests in the last " << print_duration(lastUpdated - serverStartTime) << ": "
-                                               << "[Android: " << androidPush.toString() << "], "
-                                               << "[iOS: " << iosPush.toString() << "], "
-                                               << "[Unified: " << unifiedPush.toString() << "]" << std::endl;
-            ss << "Requests: " << requestRate << " per second." << std::endl;
+            auto ret = fmt::format("Listens: {}, Puts: {}, PushListeners: {}\n"
+                        "Push requests in the last {}: [Android: {}], [iOS: {}], [Unified: {}]\n"
+                        "Requests: {} per second.",
+                        listenCount, putCount, pushListenersCount,
+                        print_duration(lastUpdated - serverStartTime),
+                        androidPush.toString(), iosPush.toString(), unifiedPush.toString(),
+                        requestRate);
             if (nodeInfo) {
                 auto& ipv4 = nodeInfo->ipv4;
                 if (ipv4.table_depth > 1)
-                    ss << "IPv4 Network estimation: " << ipv4.getNetworkSizeEstimation() << std::endl;;
+                    ret += fmt::format("IPv4 Network estimation: {}\n", ipv4.getNetworkSizeEstimation());
                 auto& ipv6 = nodeInfo->ipv6;
                 if (ipv6.table_depth > 1)
-                    ss << "IPv6 Network estimation: " << ipv6.getNetworkSizeEstimation() << std::endl;;
+                    ret += fmt::format("IPv6 Network estimation: {}\n", ipv6.getNetworkSizeEstimation());
             }
-            return ss.str();
+            return ret;
         }
 
         /**
diff --git a/include/opendht/http.h b/include/opendht/http.h
index f379a0be693e1c20ee160bae4016b6228949b86b..219fc5f6f207d009885d3922ef5299557e433db6 100644
--- a/include/opendht/http.h
+++ b/include/opendht/http.h
@@ -72,7 +72,7 @@ class OPENDHT_PUBLIC Url
 {
 public:
     Url() = default;
-    Url(const std::string& url);
+    Url(std::string_view url);
     std::string url;
     std::string protocol {"http"};
     std::string host;
diff --git a/include/opendht/utils.h b/include/opendht/utils.h
index be574cbe685b7d912e5ecf4294416ca70730f9c0..efdd576a79673a9abc528473f04cdf11036db02b 100644
--- a/include/opendht/utils.h
+++ b/include/opendht/utils.h
@@ -21,6 +21,7 @@
 #include "def.h"
 
 #include <msgpack.hpp>
+#include <fmt/format.h>
 
 #include <chrono>
 #include <random>
@@ -60,7 +61,7 @@ void erase_if(std::map<Key, Item>& map, const Condition& condition)
  * Split "[host]:port" or "host:port" to pair<"host", "port">.
  */
 OPENDHT_PUBLIC std::pair<std::string, std::string>
-splitPort(const std::string& s);
+splitPort(std::string_view s);
 
 class OPENDHT_PUBLIC DhtException : public std::runtime_error {
 public:
@@ -84,37 +85,23 @@ using duration = clock::duration;
 time_point from_time_t(std::time_t t);
 std::time_t to_time_t(time_point t);
 
-inline std::string
-to_str(double d) {
-    char buf[16];
-    auto ret = snprintf(buf, sizeof(buf), "%.3g", d);
-    return (ret < 0) ? std::to_string(d) : std::string(buf, ret);
-}
-
-/**
- * Converts std::chrono::duration to floating-point seconds.
- */
-template <class DT>
-static double
-print_dt(DT d) {
-    return std::chrono::duration_cast<std::chrono::duration<double>>(d).count();
-}
-
 template <class DT>
 static std::string
 print_duration(DT d) {
     if (d < std::chrono::seconds(0)) {
         return "-" + print_duration(-d);
     } else if (d < std::chrono::milliseconds(1)) {
-        return to_str(std::chrono::duration_cast<std::chrono::duration<double, std::micro>>(d).count()) +  " us";
+        return fmt::format("{:.3g} us", std::chrono::duration_cast<std::chrono::duration<double, std::micro>>(d).count());
     } else if (d < std::chrono::seconds(1)) {
-        return to_str(std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(d).count()) +  " ms";
+        return fmt::format("{:.3g} ms", std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(d).count());
     } else if (d < std::chrono::minutes(1)) {
-        return to_str(std::chrono::duration_cast<std::chrono::duration<double>>(d).count()) +  " s";
+        return fmt::format("{:.3g} s", std::chrono::duration_cast<std::chrono::duration<double>>(d).count());
     } else if (d < std::chrono::hours(1)) {
-        return to_str(std::chrono::duration_cast<std::chrono::duration<double, std::ratio<60>>>(d).count()) +  " min";
+        return fmt::format("{:.3g} min", std::chrono::duration_cast<std::chrono::duration<double, std::ratio<60>>>(d).count());
+    } else if (d < std::chrono::hours(72)) {
+        return fmt::format("{:.3g} h", std::chrono::duration_cast<std::chrono::duration<double, std::ratio<3600>>>(d).count());
     } else {
-        return to_str(std::chrono::duration_cast<std::chrono::duration<double, std::ratio<3600>>>(d).count()) +  " h";
+        return fmt::format("{:.3g} days", std::chrono::duration_cast<std::chrono::duration<double, std::ratio<86400>>>(d).count());
     }
 }
 
diff --git a/src/dht.cpp b/src/dht.cpp
index 00675d99e60177cdad82da31d30073702d7aca9e..3be090848ac1dd0ab2deabe46c76e3b8c5587857 100644
--- a/src/dht.cpp
+++ b/src/dht.cpp
@@ -904,7 +904,7 @@ Dht::listenTo(const InfoHash& id, sa_family_t af, ValueCallback cb, Value::Filte
 {
     if (!isRunning(af))
         return 0;
-       // logger__ERR("[search %s IPv%c] search_time is now in %lfs", sr->id.toString().c_str(), (sr->af == AF_INET) ? '4' : '6', print_dt(tm-clock::now()));
+       // logger__ERR("[search %s IPv%c] search_time is now in %lfs", sr->id.toString().c_str(), (sr->af == AF_INET) ? '4' : '6', print_duration(tm-clock::now()));
 
     //logger__WARN("listenTo %s", id.toString().c_str());
     auto& srs = searches(af);
diff --git a/src/dht_proxy_client.cpp b/src/dht_proxy_client.cpp
index 6a1e6c54fb95694fe4127bb2c372ae70724fa8b4..9d8849961d2a0e15860bc72485ab4e67d59f9d92 100644
--- a/src/dht_proxy_client.cpp
+++ b/src/dht_proxy_client.cpp
@@ -813,8 +813,8 @@ SockAddr
 DhtProxyClient::parsePublicAddress(const Json::Value& val)
 {
     auto public_ip = val.asString();
-    auto hostAndService = splitPort(public_ip);
-    auto sa = SockAddr::resolve(hostAndService.first);
+    auto [host, service] = splitPort(public_ip);
+    auto sa = SockAddr::resolve(host);
     if (sa.empty()) return {};
     return sa.front().getMappedIPv4();
 }
diff --git a/src/http.cpp b/src/http.cpp
index d0f3e01f7075113ef8999d5e105e0f4b1f631609..930eea1951920069be8033621cac42e2b150fe5d 100644
--- a/src/http.cpp
+++ b/src/http.cpp
@@ -54,7 +54,7 @@ constexpr const char HTTPS_PROTOCOL[] = "https://";
 constexpr const char ORIGIN_PROTOCOL[] = "//";
 constexpr unsigned MAX_REDIRECTS {5};
 
-Url::Url(const std::string& url): url(url)
+Url::Url(std::string_view url): url(url)
 {
     size_t addr_begin = 0;
     // protocol
@@ -69,10 +69,9 @@ Url::Url(const std::string& url): url(url)
     size_t addr_size = url.substr(addr_begin).find("/");
     if (addr_size == std::string::npos)
         addr_size = url.size() - addr_begin;
-    auto host_service = splitPort(url.substr(addr_begin, addr_size));
-    host = host_service.first;
-    if (!host_service.second.empty())
-        service = host_service.second;
+    auto [h, s] = splitPort(url.substr(addr_begin, addr_size));
+    host = std::move(h);
+    service = std::move(s);
     // target, query and fragment
     size_t query_begin = url.find("?");
     auto addr_end = addr_begin + addr_size;
diff --git a/src/utils.cpp b/src/utils.cpp
index 63cdc5678f9d07df7fad5b1db500624b3d7f788d..4a4ada33cd1abd45d2982e927b21342f1752b5d5 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -44,23 +44,23 @@ const HexMap hex_map = {};
 static constexpr std::array<uint8_t, 12> MAPPED_IPV4_PREFIX {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}};
 
 std::pair<std::string, std::string>
-splitPort(const std::string& s) {
+splitPort(std::string_view s) {
     if (s.empty())
         return {};
     if (s[0] == '[') {
         std::size_t closure = s.find_first_of(']');
         std::size_t found = s.find_last_of(':');
-        if (closure == std::string::npos)
-            return {s, ""};
-        if (found == std::string::npos or found < closure)
-            return {s.substr(1,closure-1), ""};
-        return {s.substr(1,closure-1), s.substr(found+1)};
+        if (closure == std::string_view::npos)
+            return {std::string(s), ""};
+        if (found == std::string_view::npos or found < closure)
+            return {std::string(s.substr(1,closure-1)), ""};
+        return {std::string(s.substr(1,closure-1)), std::string(s.substr(found+1))};
     }
     std::size_t found = s.find_last_of(':');
     std::size_t first = s.find_first_of(':');
-    if (found == std::string::npos or found != first)
-        return {s, ""};
-    return {s.substr(0,found), s.substr(found+1)};
+    if (found == std::string_view::npos or found != first)
+        return {std::string(s), ""};
+    return {std::string(s.substr(0,found)), std::string(s.substr(found+1))};
 }
 
 std::vector<SockAddr>
diff --git a/tools/dhtchat.cpp b/tools/dhtchat.cpp
index a1c6d8d4b50856a21f24360927348befe791225a..9c4c3117f855c373fce8cbb7a1e3599541b1b512 100644
--- a/tools/dhtchat.cpp
+++ b/tools/dhtchat.cpp
@@ -107,8 +107,8 @@ main(int argc, char **argv)
                     token = dht.listen<dht::ImMessage>(room, [&](dht::ImMessage&& msg) {
                         if (msg.from != myid)
                             std::cout << msg.from.toString() << " at " << printTime(msg.date)
-                                      << " (took " << print_dt(std::chrono::system_clock::now() - std::chrono::system_clock::from_time_t(msg.date))
-                                      << "s) " << (msg.to == myid ? "ENCRYPTED ":"") << ": " << msg.id << " - " << msg.msg << std::endl;
+                                      << " (took " << print_duration(std::chrono::system_clock::now() - std::chrono::system_clock::from_time_t(msg.date))
+                                      << ") " << (msg.to == myid ? "ENCRYPTED ":"") << ": " << msg.id << " - " << msg.msg << std::endl;
                         return true;
                     });
                     connected = true;