diff --git a/vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/service/NodeInfo.java b/vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/service/NodeInfo.java
index 8de4ace05add6b69ad54523b3c5e18c06cf08064..77e86146bea92000cefd2600ff981b994b74b800 100644
--- a/vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/service/NodeInfo.java
+++ b/vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/service/NodeInfo.java
@@ -128,17 +128,14 @@ public class NodeInfo {
     }
 
     /**
-     * Credits: https://stackoverflow.com/a/16576773/771431
+     * Credits: https://stackoverflow.com/a/24805871/771431
      */
     private String getHumanReadableSize(long bytes) {
-        int u = 0;
-        for (; bytes > 1024 * 1024; bytes >>= 10) {
-            u++;
+        if (bytes < 1024) {
+            return bytes + " B";
         }
-        if (bytes > 1024) {
-            u++;
-        }
-        return String.format("%.1f %cB", bytes / 1024f, " kMGTPE".charAt(u));
+        int z = (63 - Long.numberOfLeadingZeros(bytes)) / 10;
+        return String.format("%.1f %sB", (double) bytes / (1L << (z * 10)), " KMGTPE".charAt(z));
     }
 
     public boolean isFolder() {
diff --git a/vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/service/NodesService.java b/vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/service/NodesService.java
index 018ccc24e4fd05ab06e1a6b4e06aa78bacd50e04..d8a5b4e0785f5eae5f12aa6a95a73ecf7c724c3e 100644
--- a/vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/service/NodesService.java
+++ b/vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/service/NodesService.java
@@ -3,7 +3,6 @@ package it.inaf.ia2.vospace.ui.service;
 import it.inaf.ia2.aa.data.User;
 import it.inaf.ia2.vospace.ui.client.VOSpaceClient;
 import it.inaf.ia2.vospace.ui.data.ListNodeData;
-import it.inaf.oats.vospace.datamodel.NodeProperties;
 import it.inaf.oats.vospace.datamodel.NodeUtils;
 import java.io.IOException;
 import java.io.StringWriter;
@@ -85,20 +84,24 @@ public class NodesService {
     }
 
     private String getIcon(NodeInfo nodeInfo) {
-        String html = "<span class=\"icon ";
-        if (nodeInfo.isFile() && nodeInfo.isBusy()) {
-            html += "gear";
+        String html = "";
+        if (nodeInfo.isBusy()) {
+            html += "<span class=\"node-busy\"><span role=\"status\" class=\"spinner-border\"><span class=\"sr-only\">Loading...</span></span>";
+        }
+        html += "<span class=\"icon ";
+        if (nodeInfo.isFolder()) {
+            html += "folder";
         } else {
-            if (nodeInfo.isFolder()) {
-                html += "folder";
-            } else {
-                html += "file";
-            }
-            if (nodeInfo.isAsyncTrans()) {
-                html += "-x";
-            }
+            html += "file";
+        }
+        if (nodeInfo.isAsyncTrans()) {
+            html += "-x";
+        }
+        html += "-icon\"></span>";
+        if (nodeInfo.isBusy()) {
+            html += "</span>";
         }
-        html += "-icon\"></span>&nbsp;";
+        html += "&nbsp;";
         return html;
     }
 
diff --git a/vospace-ui-backend/src/test/java/it/inaf/ia2/vospace/ui/service/NodeInfoTest.java b/vospace-ui-backend/src/test/java/it/inaf/ia2/vospace/ui/service/NodeInfoTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..f113953ce11b382eb568c499d8f097d0276fb1db
--- /dev/null
+++ b/vospace-ui-backend/src/test/java/it/inaf/ia2/vospace/ui/service/NodeInfoTest.java
@@ -0,0 +1,67 @@
+package it.inaf.ia2.vospace.ui.service;
+
+import net.ivoa.xml.vospace.v2.DataNode;
+import net.ivoa.xml.vospace.v2.Node;
+import net.ivoa.xml.vospace.v2.Property;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import org.junit.jupiter.api.Test;
+
+public class NodeInfoTest {
+
+    private static final String AUTHORITY = "example.com!vospace";
+
+    @Test
+    public void testZero() {
+        testNodeLength(0, "0 B");
+    }
+
+    @Test
+    public void testSizeBytes() {
+        testNodeLength(5, "5 B");
+    }
+
+    @Test
+    public void testSizeKilo() {
+        testNodeLength(1024, "1.0 KB");
+    }
+
+    @Test
+    public void testSizeMega() {
+        testNodeLength(149639144, "142.7 MB");
+    }
+
+    @Test
+    public void testSizeGiga() {
+        testNodeLength(483286324544L, "450.1 GB");
+    }
+
+    @Test
+    public void testSizeTera() {
+        testNodeLength(6963696737140L, "6.3 TB");
+    }
+
+    @Test
+    public void testSizePeta() {
+        testNodeLength(6963696737150000L, "6.2 PB");
+    }
+
+    private void testNodeLength(long bytes, String expectedText) {
+        DataNode node = getDataNode();
+        setLength(node, bytes);
+        NodeInfo nodeInfo = new NodeInfo(node, AUTHORITY);
+        assertEquals(expectedText, nodeInfo.getSize());
+    }
+
+    private DataNode getDataNode() {
+        DataNode node = new DataNode();
+        node.setUri("vos://example.com!vospace/mynode");
+        return node;
+    }
+
+    private void setLength(Node node, long length) {
+        Property lengthProperty = new Property();
+        lengthProperty.setUri("ivo://ivoa.net/vospace/core#length");
+        lengthProperty.setValue(String.valueOf(length));
+        node.getProperties().add(lengthProperty);
+    }
+}
diff --git a/vospace-ui-frontend/src/App.vue b/vospace-ui-frontend/src/App.vue
index 9af19205e9a77ccfc64c93945dd3705765b9ba74..566eb288a621bd7838658eed94a85ea37ddc0b6f 100644
--- a/vospace-ui-frontend/src/App.vue
+++ b/vospace-ui-frontend/src/App.vue
@@ -20,6 +20,7 @@
 <script>
 import { mapState } from 'vuex'
 import TopMenu from './components/TopMenu.vue'
+import client from 'api-client'
 
 export default {
   name: 'App',
@@ -32,6 +33,7 @@ export default {
   mounted() {
     this.$store.dispatch('loadJobs');
     this.$store.dispatch('loadUserInfo');
+    setInterval(client.keepalive, 60000);
   }
 }
 </script>
@@ -78,4 +80,19 @@ export default {
   height: 100%;
   width: 100%;
 }
+
+.node-busy {
+  position: relative;
+  padding-right: 3px;
+}
+
+.node-busy .spinner-border {
+  position: absolute;
+  left: -5px;
+  font-size: 7px;
+  height: 26px;
+  width: 26px;
+  top: -7px;
+  color: #3293f2;
+}
 </style>
diff --git a/vospace-ui-frontend/src/api/mock/index.js b/vospace-ui-frontend/src/api/mock/index.js
index 9924ec950efcf6aa1963bd3e47dbdfac6750c471..e92cd1114526de3592eb3d63d6ef420d6526bac6 100644
--- a/vospace-ui-frontend/src/api/mock/index.js
+++ b/vospace-ui-frontend/src/api/mock/index.js
@@ -57,5 +57,8 @@ export default {
   },
   deleteNode() {
     return fetch({});
+  },
+  keepalive() {
+    return fetch({});    
   }
 }
diff --git a/vospace-ui-frontend/src/api/server/index.js b/vospace-ui-frontend/src/api/server/index.js
index 32fc75c95e8fa0c34ca568d1ac3e450a2e13a6bf..d7931218a42398532d792b5b379ed3947049328f 100644
--- a/vospace-ui-frontend/src/api/server/index.js
+++ b/vospace-ui-frontend/src/api/server/index.js
@@ -136,5 +136,16 @@ export default {
         'Cache-Control': 'no-cache'
       }
     }, true, true);
+  },
+  keepalive() {
+    let url = BASE_API_URL + 'keepalive';
+    return apiRequest({
+      method: 'GET',
+      url: url,
+      withCredentials: true,
+      headers: {
+        'Cache-Control': 'no-cache'
+      }
+    }, false, false);
   }
 }
diff --git a/vospace-ui-frontend/src/assets/css/fonts.css b/vospace-ui-frontend/src/assets/css/fonts.css
index d24f83f18836fd04721e7c3c3811fc979d0531fd..1041dbd17584a2f70665f6ed4f0226e19ea5e09e 100644
--- a/vospace-ui-frontend/src/assets/css/fonts.css
+++ b/vospace-ui-frontend/src/assets/css/fonts.css
@@ -32,7 +32,3 @@
 .folder-link-icon {
   background-image: url("data:image/svg+xml,%3Csvg data-v-41be6633='' viewBox='0 0 16 16' width='1em' height='1em' focusable='false' role='img' aria-label='folder symlink' xmlns='http://www.w3.org/2000/svg' fill='currentColor' class='bi-folder-symlink mx-auto b-icon bi'%3E%3Cg data-v-41be6633=''%3E%3Cpath d='M11.798 8.271l-3.182 1.97c-.27.166-.616-.036-.616-.372V9.1s-2.571-.3-4 2.4c.571-4.8 3.143-4.8 4-4.8v-.769c0-.336.346-.538.616-.371l3.182 1.969c.27.166.27.576 0 .742z'%3E%3C/path%3E%3Cpath d='M.5 3l.04.87a1.99 1.99 0 0 0-.342 1.311l.637 7A2 2 0 0 0 2.826 14h10.348a2 2 0 0 0 1.991-1.819l.637-7A2 2 0 0 0 13.81 3H9.828a2 2 0 0 1-1.414-.586l-.828-.828A2 2 0 0 0 6.172 1H2.5a2 2 0 0 0-2 2zm.694 2.09A1 1 0 0 1 2.19 4h11.62a1 1 0 0 1 .996 1.09l-.636 7a1 1 0 0 1-.996.91H2.826a1 1 0 0 1-.995-.91l-.637-7zM6.172 2a1 1 0 0 1 .707.293L7.586 3H2.19c-.24 0-.47.042-.684.12L1.5 2.98a1 1 0 0 1 1-.98h3.672z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E");
 }
-
-.gear-icon {
-  background-image: url("data:image/svg+xml,%3Csvg data-v-41be6633='' viewBox='0 0 16 16' width='1em' height='1em' focusable='false' role='img' aria-label='gear' xmlns='http://www.w3.org/2000/svg' fill='currentColor' class='bi-gear mx-auto b-icon bi'%3E%3Cg data-v-41be6633=''%3E%3Cpath d='M8 4.754a3.246 3.246 0 1 0 0 6.492 3.246 3.246 0 0 0 0-6.492zM5.754 8a2.246 2.246 0 1 1 4.492 0 2.246 2.246 0 0 1-4.492 0z'%3E%3C/path%3E%3Cpath d='M9.796 1.343c-.527-1.79-3.065-1.79-3.592 0l-.094.319a.873.873 0 0 1-1.255.52l-.292-.16c-1.64-.892-3.433.902-2.54 2.541l.159.292a.873.873 0 0 1-.52 1.255l-.319.094c-1.79.527-1.79 3.065 0 3.592l.319.094a.873.873 0 0 1 .52 1.255l-.16.292c-.892 1.64.901 3.434 2.541 2.54l.292-.159a.873.873 0 0 1 1.255.52l.094.319c.527 1.79 3.065 1.79 3.592 0l.094-.319a.873.873 0 0 1 1.255-.52l.292.16c1.64.893 3.434-.902 2.54-2.541l-.159-.292a.873.873 0 0 1 .52-1.255l.319-.094c1.79-.527 1.79-3.065 0-3.592l-.319-.094a.873.873 0 0 1-.52-1.255l.16-.292c.893-1.64-.902-3.433-2.541-2.54l-.292.159a.873.873 0 0 1-1.255-.52l-.094-.319zm-2.633.283c.246-.835 1.428-.835 1.674 0l.094.319a1.873 1.873 0 0 0 2.693 1.115l.291-.16c.764-.415 1.6.42 1.184 1.185l-.159.292a1.873 1.873 0 0 0 1.116 2.692l.318.094c.835.246.835 1.428 0 1.674l-.319.094a1.873 1.873 0 0 0-1.115 2.693l.16.291c.415.764-.42 1.6-1.185 1.184l-.291-.159a1.873 1.873 0 0 0-2.693 1.116l-.094.318c-.246.835-1.428.835-1.674 0l-.094-.319a1.873 1.873 0 0 0-2.692-1.115l-.292.16c-.764.415-1.6-.42-1.184-1.185l.159-.291A1.873 1.873 0 0 0 1.945 8.93l-.319-.094c-.835-.246-.835-1.428 0-1.674l.319-.094A1.873 1.873 0 0 0 3.06 4.377l-.16-.292c-.415-.764.42-1.6 1.185-1.184l.292.159a1.873 1.873 0 0 0 2.692-1.115l.094-.319z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E");
-}