diff --git a/pom.xml b/pom.xml
index 173995eaf..d76a2f591 100644
--- a/pom.xml
+++ b/pom.xml
@@ -84,6 +84,10 @@
       org.jenkins-ci.plugins
       bouncycastle-api
     
+    
+      org.jenkins-ci.plugins
+      cloud-stats
+    
 
     
       
diff --git a/src/main/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesComputer.java b/src/main/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesComputer.java
index a679b02a7..d6461ac75 100644
--- a/src/main/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesComputer.java
+++ b/src/main/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesComputer.java
@@ -1,5 +1,6 @@
 package org.csanchez.jenkins.plugins.kubernetes;
 
+import edu.umd.cs.findbugs.annotations.CheckForNull;
 import edu.umd.cs.findbugs.annotations.NonNull;
 import hudson.model.Computer;
 import hudson.model.Executor;
@@ -30,6 +31,8 @@
 import jenkins.model.Jenkins;
 import org.acegisecurity.Authentication;
 import org.apache.commons.lang.StringUtils;
+import org.jenkinsci.plugins.cloudstats.ProvisioningActivity;
+import org.jenkinsci.plugins.cloudstats.TrackedItem;
 import org.jenkinsci.plugins.kubernetes.auth.KubernetesAuthException;
 import org.kohsuke.stapler.QueryParameter;
 import org.kohsuke.stapler.StaplerRequest2;
@@ -41,7 +44,7 @@
 /**
  * @author Carlos Sanchez carlos@apache.org
  */
-public class KubernetesComputer extends AbstractCloudComputer {
+public class KubernetesComputer extends AbstractCloudComputer implements TrackedItem {
     private static final Logger LOGGER = Logger.getLogger(KubernetesComputer.class.getName());
 
     private boolean launching;
@@ -244,4 +247,15 @@ public void setAcceptingTasks(boolean acceptingTasks) {
             launching = false;
         }
     }
+
+    @CheckForNull
+    @Override
+    public ProvisioningActivity.Id getId() {
+        KubernetesSlave slave = getNode();
+        if (slave != null) {
+            return slave.getId();
+        }
+
+        return null;
+    }
 }
diff --git a/src/main/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesSlave.java b/src/main/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesSlave.java
index 601514b73..7d6266105 100644
--- a/src/main/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesSlave.java
+++ b/src/main/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesSlave.java
@@ -49,6 +49,8 @@
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.Validate;
 import org.csanchez.jenkins.plugins.kubernetes.pod.retention.PodRetention;
+import org.jenkinsci.plugins.cloudstats.ProvisioningActivity;
+import org.jenkinsci.plugins.cloudstats.TrackedItem;
 import org.jenkinsci.plugins.durabletask.executors.OnceRetentionStrategy;
 import org.jenkinsci.plugins.kubernetes.auth.KubernetesAuthException;
 import org.jenkinsci.plugins.workflow.flow.FlowExecutionOwner;
@@ -58,7 +60,7 @@
 /**
  * @author Carlos Sanchez carlos@apache.org
  */
-public class KubernetesSlave extends AbstractCloudSlave {
+public class KubernetesSlave extends AbstractCloudSlave implements TrackedItem {
 
     private static final Logger LOGGER = Logger.getLogger(KubernetesSlave.class.getName());
 
@@ -85,6 +87,9 @@ public class KubernetesSlave extends AbstractCloudSlave {
     @CheckForNull
     private transient Pod pod;
 
+    @NonNull
+    private final ProvisioningActivity.Id id;
+
     @NonNull
     public PodTemplate getTemplate() throws IllegalStateException {
         // Look up updated pod template after a restart
@@ -210,6 +215,7 @@ protected KubernetesSlave(
         this.cloudName = cloudName;
         this.template = template;
         this.podTemplateId = template.getId();
+        this.id = new ProvisioningActivity.Id(cloudName, template.getName(), name);
     }
 
     public String getCloudName() {
@@ -478,6 +484,12 @@ private void deleteSlavePod(TaskListener listener, KubernetesClient client) {
         listener.getLogger().println(msg);
     }
 
+    @CheckForNull
+    @Override
+    public ProvisioningActivity.Id getId() {
+        return id;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
diff --git a/src/main/java/org/csanchez/jenkins/plugins/kubernetes/StandardPlannedNodeBuilder.java b/src/main/java/org/csanchez/jenkins/plugins/kubernetes/StandardPlannedNodeBuilder.java
index f27952153..e719b8b61 100644
--- a/src/main/java/org/csanchez/jenkins/plugins/kubernetes/StandardPlannedNodeBuilder.java
+++ b/src/main/java/org/csanchez/jenkins/plugins/kubernetes/StandardPlannedNodeBuilder.java
@@ -1,10 +1,12 @@
 package org.csanchez.jenkins.plugins.kubernetes;
 
-import hudson.Util;
 import hudson.model.Descriptor;
+import hudson.model.Node;
 import hudson.slaves.NodeProvisioner;
 import java.io.IOException;
 import java.util.concurrent.CompletableFuture;
+import org.jenkinsci.plugins.cloudstats.ProvisioningActivity;
+import org.jenkinsci.plugins.cloudstats.TrackedPlannedNode;
 
 /**
  * The default {@link PlannedNodeBuilder} implementation, in case there is other registered.
@@ -14,20 +16,24 @@ public class StandardPlannedNodeBuilder extends PlannedNodeBuilder {
     public NodeProvisioner.PlannedNode build() {
         KubernetesCloud cloud = getCloud();
         PodTemplate t = getTemplate();
-        CompletableFuture f;
-        String displayName;
+        CompletableFuture f;
+        ProvisioningActivity.Id id = null;
         try {
             KubernetesSlave agent = KubernetesSlave.builder()
                     .podTemplate(t.isUnwrapped() ? t : cloud.getUnwrappedTemplate(t))
                     .cloud(cloud)
                     .build();
-            displayName = agent.getDisplayName();
+            // always use one sourced from the slave we are provisioning so the identity is maintained
+            id = agent.getId();
             f = CompletableFuture.completedFuture(agent);
         } catch (IOException | Descriptor.FormException e) {
-            displayName = null;
-            f = new CompletableFuture();
-            f.completeExceptionally(e);
+            f = CompletableFuture.failedFuture(e);
         }
-        return new NodeProvisioner.PlannedNode(Util.fixNull(displayName), f, getNumExecutors());
+
+        if (id == null) {
+            id = new ProvisioningActivity.Id(cloud.name, t.getName());
+        }
+
+        return new TrackedPlannedNode(id, getNumExecutors(), f);
     }
 }
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesSlaveTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesSlaveTest.java
index 1d1f40645..75ac64da4 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesSlaveTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesSlaveTest.java
@@ -45,6 +45,7 @@
 import org.csanchez.jenkins.plugins.kubernetes.pod.retention.OnFailure;
 import org.csanchez.jenkins.plugins.kubernetes.pod.retention.PodRetention;
 import org.csanchez.jenkins.plugins.kubernetes.volumes.PodVolume;
+import org.jenkinsci.plugins.cloudstats.ProvisioningActivity;
 import org.jenkinsci.plugins.kubernetes.auth.KubernetesAuthException;
 import org.junit.Rule;
 import org.junit.Test;
@@ -164,6 +165,18 @@ private interface GetPodTestCase {
         void test(KubernetesCloud cloud, KubernetesSlave slave, PodResource podResource) throws Exception;
     }
 
+    @Test
+    public void testProvisioningActivityId() throws Descriptor.FormException, IOException {
+        PodTemplate pt = new PodTemplate("x");
+        pt.setName("Template");
+        KubernetesSlave slave = new KubernetesSlave("Node", pt, "bar", "Cloud", "", null, null);
+        ProvisioningActivity.Id id = slave.getId();
+        assertNotNull(id);
+        assertEquals(id.getCloudName(), "Cloud");
+        assertEquals(id.getTemplateName(), "Template");
+        assertEquals(id.getNodeName(), "Node");
+    }
+
     @Test
     public void testGetPodRetention() {
         try {
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/StandardPlannedNodeBuilderTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/StandardPlannedNodeBuilderTest.java
new file mode 100644
index 000000000..4e2a8bdb2
--- /dev/null
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/StandardPlannedNodeBuilderTest.java
@@ -0,0 +1,36 @@
+package org.csanchez.jenkins.plugins.kubernetes;
+
+import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.assertRegex;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import hudson.slaves.NodeProvisioner;
+import org.jenkinsci.plugins.cloudstats.ProvisioningActivity;
+import org.jenkinsci.plugins.cloudstats.TrackedPlannedNode;
+import org.junit.Rule;
+import org.junit.Test;
+import org.jvnet.hudson.test.JenkinsRule;
+
+public class StandardPlannedNodeBuilderTest {
+
+    @Rule
+    public JenkinsRule r = new JenkinsRule();
+
+    @Test
+    public void testBuild() {
+        KubernetesCloud cloud = new KubernetesCloud("Cloud");
+        PodTemplate template = new PodTemplate("t");
+        template.setName("Template");
+        StandardPlannedNodeBuilder builder = new StandardPlannedNodeBuilder();
+        builder.cloud(cloud);
+        builder.template(template);
+        builder.numExecutors(1);
+
+        NodeProvisioner.PlannedNode plannedNode = builder.build();
+        assertTrue(plannedNode instanceof TrackedPlannedNode);
+        ProvisioningActivity.Id id = ((TrackedPlannedNode) plannedNode).getId();
+        assertEquals(id.getCloudName(), "Cloud");
+        assertEquals(id.getTemplateName(), "Template");
+        assertRegex(id.getNodeName(), "template-\\w{5}");
+    }
+}