diff --git a/src/ringdht/ringaccount.cpp b/src/ringdht/ringaccount.cpp
index 861b5f8577914efd8c00ae8bd23fef5cd6cd7609..3bc9f5bc69115e2b444767aa88e33c9bf1a8ef73 100644
--- a/src/ringdht/ringaccount.cpp
+++ b/src/ringdht/ringaccount.cpp
@@ -77,14 +77,15 @@
 
 #include <algorithm>
 #include <array>
-#include <memory>
-#include <sstream>
 #include <cctype>
 #include <cinttypes>
 #include <cstdarg>
+#include <initializer_list>
+#include <memory>
+#include <regex>
+#include <sstream>
 #include <string>
 #include <system_error>
-#include <initializer_list>
 
 namespace ring {
 
@@ -215,6 +216,7 @@ static constexpr const char * DEFAULT_TURN_SERVER = "turn.jami.net";
 static constexpr const char * DEFAULT_TURN_USERNAME = "ring";
 static constexpr const char * DEFAULT_TURN_PWD = "ring";
 static constexpr const char * DEFAULT_TURN_REALM = "ring";
+static const auto PROXY_REGEX = std::regex("(https?://)?([\\w\\.]+)(:(\\d+)|:\\[(.+)-(.+)\\])?");
 
 constexpr const char* const RingAccount::ACCOUNT_TYPE;
 /* constexpr */ const std::pair<uint16_t, uint16_t> RingAccount::DHT_PORT_RANGE {4000, 8888};
@@ -291,6 +293,10 @@ RingAccount::RingAccount(const std::string& accountID, bool /* presenceEnabled *
     turnServerPwd_ = DEFAULT_TURN_PWD;
     turnServerRealm_ = DEFAULT_TURN_REALM;
     turnEnabled_ = true;
+
+    std::ifstream proxyCache(cachePath_ + DIR_SEPARATOR_STR "dhtproxy");
+    if (proxyCache)
+      std::getline(proxyCache, proxyServerCached_);
 }
 
 RingAccount::~RingAccount()
@@ -1526,10 +1532,21 @@ RingAccount::setAccountDetails(const std::map<std::string, std::string>& details
     parseString(details, DRing::Account::ConfProperties::RING_DEVICE_NAME, ringDeviceName_);
 
     parseBool(details, DRing::Account::ConfProperties::PROXY_ENABLED, proxyEnabled_);
+    auto oldProxyServer = proxyServer_;
     parseString(details, DRing::Account::ConfProperties::PROXY_SERVER, proxyServer_);
     parseString(details, DRing::Account::ConfProperties::PROXY_PUSH_TOKEN, deviceKey_);
-    if (proxyServer_.empty())
+    // Migrate from old versions
+    if (proxyServer_.empty()
+    || ((proxyServer_ == "dhtproxy.jami.net"
+    ||  proxyServer_ == "dhtproxy.ring.cx")
+    &&  proxyServerCached_.empty()))
         proxyServer_ = DHT_DEFAULT_PROXY;
+    if (proxyServer_ != oldProxyServer) {
+        RING_DBG("DHT Proxy configuration changed, resetting cache");
+        proxyServerCached_ = {};
+        auto proxyCachePath = cachePath_ + DIR_SEPARATOR_STR "dhtproxy";
+        std::remove(proxyCachePath.c_str());
+    }
 
 #if HAVE_RINGNS
     parseString(details, DRing::Account::ConfProperties::RingNS::URI,     nameServer_);
@@ -2103,7 +2120,7 @@ RingAccount::doRegister_()
         config.dht_config.node_config.network = 0;
         config.dht_config.node_config.maintain_storage = false;
         config.dht_config.id = identity_;
-        config.proxy_server = proxyEnabled_ ? proxyServer_ : std::string();
+        config.proxy_server = getDhtProxyServer();
         config.push_node_id = getAccountID();
         config.threaded = true;
         if (not config.proxy_server.empty())
@@ -2851,6 +2868,50 @@ RingAccount::loadDhParams(const std::string path)
     }
 }
 
+std::string
+RingAccount::getDhtProxyServer()
+{
+    if (!proxyEnabled_) return {};
+    if (proxyServerCached_.empty()) {
+        std::vector<std::string> proxys;
+        // Split the list of servers
+        std::sregex_iterator begin = {proxyServer_.begin(), proxyServer_.end(), PROXY_REGEX}, end;
+        for (auto it = begin; it != end; ++it) {
+            auto &match = *it;
+            if (match[5].matched and match[6].matched) {
+                try {
+                    auto start = std::stoi(match[5]), end = std::stoi(match[6]);
+                    for (auto p = start; p <= end; p++)
+                      proxys.emplace_back(match[1].str() + match[2].str() + ":" +
+                                          std::to_string(p));
+                } catch (...) {
+                    RING_WARN("Malformed proxy, ignore it");
+                    continue;
+                }
+            } else {
+                proxys.emplace_back(match[0].str());
+            }
+        }
+        if (proxys.empty())
+          return {};
+        // Select one of the list as the current proxy.
+        auto randIt = proxys.begin();
+        std::advance(randIt, std::rand() % proxys.size());
+        proxyServerCached_ = *randIt;
+        // Cache it!
+        fileutils::check_dir(cachePath_.c_str(), 0700);
+        std::string proxyCachePath = cachePath_ + DIR_SEPARATOR_STR "dhtproxy";
+        std::ofstream file(proxyCachePath);
+        RING_DBG("Cache DHT proxy server: %s", proxyServerCached_.c_str());
+        if (file.is_open())
+            file << proxyServerCached_;
+        else
+            RING_WARN("Cannot write into %s", proxyCachePath.c_str());
+        return proxyServerCached_;
+    }
+    return proxyServerCached_;
+}
+
 void
 RingAccount::generateDhParams()
 {
diff --git a/src/ringdht/ringaccount.h b/src/ringdht/ringaccount.h
index 2bf02d69c046c1799b8a583aafcb70daab57de4e..6e33020d8e18d0c13bb1f8a104b76c2d0c93e030 100644
--- a/src/ringdht/ringaccount.h
+++ b/src/ringdht/ringaccount.h
@@ -86,7 +86,7 @@ class RingAccount : public SIPAccountBase {
         constexpr static const char* const ACCOUNT_TYPE = "RING";
         constexpr static const in_port_t DHT_DEFAULT_PORT = 4222;
         constexpr static const char* const DHT_DEFAULT_BOOTSTRAP = "bootstrap.jami.net";
-        constexpr static const char* const DHT_DEFAULT_PROXY = "dhtproxy.jami.net";
+        constexpr static const char* const DHT_DEFAULT_PROXY = "dhtproxy.jami.net:[80-100]";
         constexpr static const char* const DHT_TYPE_NS = "cx.ring";
 
         /* constexpr */ static const std::pair<uint16_t, uint16_t> DHT_PORT_RANGE;
@@ -635,7 +635,9 @@ class RingAccount : public SIPAccountBase {
          */
         bool proxyEnabled_;
         std::string proxyServer_;
+        std::string proxyServerCached_;
         std::string deviceKey_;
+        std::string getDhtProxyServer();
 
         /**
          * The TLS settings, used only if tls is chosen as a sip transport.