diff --git a/include/opendht/dht_proxy_server.h b/include/opendht/dht_proxy_server.h
index a83b07ed78d56042e1a848d8109dd7e40047558a..d0af6a87ec0f27af78e522ca99b0c1a4b2bac97a 100644
--- a/include/opendht/dht_proxy_server.h
+++ b/include/opendht/dht_proxy_server.h
@@ -230,6 +230,8 @@ private:
     Scheduler scheduler_;
     std::thread schedulerThread_;
 
+    Sp<Scheduler::Job> printStatsJob_;
+
     // Handle client quit for listen.
     // NOTE: can be simplified when we will supports restbed 5.0
     std::thread listenThread_;
diff --git a/src/dht_proxy_server.cpp b/src/dht_proxy_server.cpp
index e46d6e7551cc071968535e587d26318fa6f20c0a..cd6623d9492d34e47427a0c8fdc74128bfe6fb5c 100644
--- a/src/dht_proxy_server.cpp
+++ b/src/dht_proxy_server.cpp
@@ -45,6 +45,7 @@ struct DhtProxyServer::SearchPuts {
     std::map<dht::Value::Id, PermanentPut> puts;
 };
 
+constexpr const std::chrono::minutes PRINT_STATS_PERIOD {2};
 
 DhtProxyServer::DhtProxyServer(std::shared_ptr<DhtRunner> dht, in_port_t port , const std::string& pushServer)
 : dht_(dht) , pushServer_(pushServer)
@@ -122,6 +123,12 @@ DhtProxyServer::DhtProxyServer(std::shared_ptr<DhtRunner> dht, in_port_t port ,
         while (not service_->is_up() and not stopListeners) {
             std::this_thread::sleep_for(std::chrono::seconds(1));
         }
+        printStatsJob_ = scheduler_.add(scheduler_.time() + PRINT_STATS_PERIOD, [this]{
+            if (service_->is_up() and not stopListeners) {
+                std::cout << getStats().toString() << std::endl;
+                scheduler_.edit(printStatsJob_, scheduler_.time() + PRINT_STATS_PERIOD);
+            }
+        });
         while (service_->is_up()  and not stopListeners) {
             std::unique_lock<std::mutex> lock(schedulerLock_);
             auto next = scheduler_.run();
@@ -143,6 +150,7 @@ DhtProxyServer::~DhtProxyServer()
 void
 DhtProxyServer::stop()
 {
+    printStatsJob_->cancel();
     service_->stop();
     {
         std::lock_guard<std::mutex> lock(lockListener_);