diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/rendezvous/RendezvousPoller.java b/bramble-api/src/main/java/org/briarproject/bramble/api/rendezvous/RendezvousPoller.java
index e6f473fdfe0a37c045355ab438b6666f0b0aae56..a4eb0dcb6745db8dc33229873608ac99010d9be2 100644
--- a/bramble-api/src/main/java/org/briarproject/bramble/api/rendezvous/RendezvousPoller.java
+++ b/bramble-api/src/main/java/org/briarproject/bramble/api/rendezvous/RendezvousPoller.java
@@ -1,6 +1,6 @@
 package org.briarproject.bramble.api.rendezvous;
 
-import org.briarproject.bramble.api.plugin.TransportId;
+import org.briarproject.bramble.api.contact.PendingContactId;
 
 /**
  * Interface for the poller that makes rendezvous connections to pending
@@ -8,5 +8,5 @@ import org.briarproject.bramble.api.plugin.TransportId;
  */
 public interface RendezvousPoller {
 
-	long getLastPollTime(TransportId t);
+	long getLastPollTime(PendingContactId p);
 }
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/rendezvous/RendezvousPollerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/rendezvous/RendezvousPollerImpl.java
index 797929fcedbae0944e7ad19a9fda0c1171afdbaa..6f5ec72b70fed1c1b1306dd3b51510b8e81ba8be 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/rendezvous/RendezvousPollerImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/rendezvous/RendezvousPollerImpl.java
@@ -90,7 +90,7 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
 	private final Clock clock;
 
 	private final AtomicBoolean used = new AtomicBoolean(false);
-	private final Map<TransportId, Long> lastPollTimes =
+	private final Map<PendingContactId, Long> lastPollTimes =
 			new ConcurrentHashMap<>();
 
 	// Executor that runs one task at a time
@@ -126,8 +126,8 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
 	}
 
 	@Override
-	public long getLastPollTime(TransportId t) {
-		Long time = lastPollTimes.get(t);
+	public long getLastPollTime(PendingContactId p) {
+		Long time = lastPollTimes.get(p);
 		return time == null ? 0 : time;
 	}
 
@@ -227,6 +227,7 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
 	private void removePendingContact(PendingContactId p) {
 		// We can come here twice if a pending contact expires and is removed
 		if (cryptoStates.remove(p) == null) return;
+		lastPollTimes.remove(p);
 		for (PluginState ps : pluginStates.values()) {
 			RendezvousEndpoint endpoint = ps.endpoints.remove(p);
 			if (endpoint != null) tryToClose(endpoint, LOG, INFO);
@@ -246,9 +247,10 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
 			Handler h = new Handler(e.getKey(), t, false);
 			properties.add(new Pair<>(props, h));
 		}
-		lastPollTimes.put(t, clock.currentTimeMillis());
-		eventBus.broadcast(new RendezvousPollEvent(t,
-				new ArrayList<>(ps.endpoints.keySet())));
+		List<PendingContactId> polled = new ArrayList<>(ps.endpoints.keySet());
+		long now = clock.currentTimeMillis();
+		for (PendingContactId p : polled) lastPollTimes.put(p, now);
+		eventBus.broadcast(new RendezvousPollEvent(t, polled));
 		ps.plugin.poll(properties);
 	}
 
@@ -294,9 +296,13 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
 		for (PluginState ps : pluginStates.values()) {
 			RendezvousEndpoint endpoint = ps.endpoints.get(p);
 			if (endpoint != null) {
+				TransportId t = ps.plugin.getId();
 				TransportProperties props =
 						endpoint.getRemoteTransportProperties();
-				Handler h = new Handler(p, ps.plugin.getId(), false);
+				Handler h = new Handler(p, t, false);
+				lastPollTimes.put(p, clock.currentTimeMillis());
+				eventBus.broadcast(
+						new RendezvousPollEvent(t, singletonList(p)));
 				ps.plugin.poll(singletonList(new Pair<>(props, h)));
 			}
 		}
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/rendezvous/RendezvousPollerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/rendezvous/RendezvousPollerImplTest.java
index 902c9b8ea139d68a6e13fce59b23092647c14839..27321d748e9f23470c0662c8ed8e8c213f37647d 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/rendezvous/RendezvousPollerImplTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/rendezvous/RendezvousPollerImplTest.java
@@ -24,6 +24,7 @@ import org.briarproject.bramble.api.rendezvous.KeyMaterialSource;
 import org.briarproject.bramble.api.rendezvous.RendezvousEndpoint;
 import org.briarproject.bramble.api.rendezvous.event.RendezvousConnectionClosedEvent;
 import org.briarproject.bramble.api.rendezvous.event.RendezvousConnectionOpenedEvent;
+import org.briarproject.bramble.api.rendezvous.event.RendezvousPollEvent;
 import org.briarproject.bramble.api.system.Clock;
 import org.briarproject.bramble.test.BrambleMockTestCase;
 import org.briarproject.bramble.test.CaptureArgumentAction;
@@ -191,6 +192,9 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
 			// Poll newly added pending contact
 			oneOf(rendezvousEndpoint).getRemoteTransportProperties();
 			will(returnValue(transportProperties));
+			oneOf(clock).currentTimeMillis();
+			will(returnValue(beforeExpiry));
+			oneOf(eventBus).broadcast(with(any(RendezvousPollEvent.class)));
 			oneOf(plugin).poll(with(collectionOf(pairOf(
 					equal(transportProperties),
 					any(ConnectionHandler.class)))));
@@ -242,6 +246,9 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
 			// Poll newly added pending contact
 			oneOf(rendezvousEndpoint).getRemoteTransportProperties();
 			will(returnValue(transportProperties));
+			oneOf(clock).currentTimeMillis();
+			will(returnValue(beforeExpiry));
+			oneOf(eventBus).broadcast(with(any(RendezvousPollEvent.class)));
 			oneOf(plugin).poll(with(collectionOf(pairOf(
 					equal(transportProperties),
 					any(ConnectionHandler.class)))));
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/add/remote/PendingContactListViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/add/remote/PendingContactListViewModel.java
index 7e284712aedca8f7ae7e71b2899401cbd178035e..5c9ea749171d1f4ffeecd7c0f3edad68f463619a 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/contact/add/remote/PendingContactListViewModel.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/add/remote/PendingContactListViewModel.java
@@ -18,7 +18,6 @@ import org.briarproject.bramble.api.event.Event;
 import org.briarproject.bramble.api.event.EventBus;
 import org.briarproject.bramble.api.event.EventListener;
 import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
-import org.briarproject.bramble.api.plugin.TorConstants;
 import org.briarproject.bramble.api.rendezvous.RendezvousPoller;
 import org.briarproject.bramble.api.rendezvous.event.RendezvousPollEvent;
 
@@ -83,14 +82,14 @@ public class PendingContactListViewModel extends AndroidViewModel
 	private void loadPendingContacts() {
 		dbExecutor.execute(() -> {
 			try {
-				long lastPoll =
-						rendezvousPoller.getLastPollTime(TorConstants.ID);
 				Collection<Pair<PendingContact, PendingContactState>> pairs =
 						contactManager.getPendingContacts();
 				List<PendingContactItem> items = new ArrayList<>(pairs.size());
-				for (Pair<PendingContact, PendingContactState> p : pairs) {
-					items.add(new PendingContactItem(p.getFirst(),
-							p.getSecond(), lastPoll));
+				for (Pair<PendingContact, PendingContactState> pair : pairs) {
+					PendingContact p = pair.getFirst();
+					long lastPoll = rendezvousPoller.getLastPollTime(p.getId());
+					items.add(new PendingContactItem(p, pair.getSecond(),
+							lastPoll));
 				}
 				pendingContacts.postValue(items);
 			} catch (DbException e) {