diff --git a/src/dht.cpp b/src/dht.cpp
index 4f2dcc644873fdca21032630774aba3852b0ac78..65ea19675117d71267d728dbd5dd7ba8d43913e1 100644
--- a/src/dht.cpp
+++ b/src/dht.cpp
@@ -2363,7 +2363,10 @@ Dht::onRefresh(Sp<Node> node, const InfoHash& hash, const Blob& token, const Val
     }
 
     auto s = store.find(hash);
-    if (s != store.end() and s->second.refresh(now, vid)) {
+    if (s != store.end()) {
+        auto expiration = s->second.refresh(now, vid, types);
+        if (expiration != time_point::max())
+            scheduler.add(expiration, std::bind(&Dht::expireStorage, this, hash));
         DHT_LOG.d(hash, node->id, "[store %s] [node %s] refreshed value %s", hash.toString().c_str(), node->toString().c_str(), std::to_string(vid).c_str());
     } else {
         DHT_LOG.d(hash, node->id, "[store %s] [node %s] got refresh for unknown value",
diff --git a/src/storage.h b/src/storage.h
index 1d5896579cde5ca05c62178e98910410583e9b36..01d3d0faed7d7dc2a44c4923292e248596957b76 100644
--- a/src/storage.h
+++ b/src/storage.h
@@ -154,15 +154,16 @@ struct Storage {
      *
      * @param now  The reference to now
      * @param vid  The value id
-     * @return true if a value storage was updated, false otherwise
+     * @return time of the next expiration, time_point::max() if no expiration
      */
-    bool refresh(const time_point& now, const Value::Id& vid) {
+    time_point refresh(const time_point& now, const Value::Id& vid, const TypeStore& types) {
         for (auto& vs : values)
             if (vs.data->id == vid) {
                 vs.created = now;
-                return true;
+                vs.expiration = std::max(vs.expiration, now + types.getType(vs.data->type).expiration);
+                return vs.expiration;
             }
-        return false;
+        return time_point::max();
     }
 
     StoreDiff remove(const InfoHash& id, Value::Id);