diff --git a/p2p/dial.go b/p2p/dial.go
index 71065c5eedc3d95c516fd378defe46f1833d96cf..b82d6d1f5181cf1d8750efaa86c7b9aa36cbd037 100644
--- a/p2p/dial.go
+++ b/p2p/dial.go
@@ -17,10 +17,9 @@ const (
 	// redialing a certain node.
 	dialHistoryExpiration = 30 * time.Second
 
-	// Discovery lookup tasks will wait for this long when
-	// no results are returned. This can happen if the table
-	// becomes empty (i.e. not often).
-	emptyLookupDelay = 10 * time.Second
+	// Discovery lookups are throttled and can only run
+	// once every few seconds.
+	lookupInterval = 4 * time.Second
 )
 
 // dialstate schedules dials and discovery lookups.
@@ -206,18 +205,19 @@ func (t *dialTask) String() string {
 func (t *discoverTask) Do(srv *Server) {
 	if t.bootstrap {
 		srv.ntab.Bootstrap(srv.BootstrapNodes)
-	} else {
-		var target discover.NodeID
-		rand.Read(target[:])
-		t.results = srv.ntab.Lookup(target)
-		// newTasks generates a lookup task whenever dynamic dials are
-		// necessary. Lookups need to take some time, otherwise the
-		// event loop spins too fast. An empty result can only be
-		// returned if the table is empty.
-		if len(t.results) == 0 {
-			time.Sleep(emptyLookupDelay)
-		}
+		return
+	}
+	// newTasks generates a lookup task whenever dynamic dials are
+	// necessary. Lookups need to take some time, otherwise the
+	// event loop spins too fast.
+	next := srv.lastLookup.Add(lookupInterval)
+	if now := time.Now(); now.Before(next) {
+		time.Sleep(next.Sub(now))
 	}
+	srv.lastLookup = time.Now()
+	var target discover.NodeID
+	rand.Read(target[:])
+	t.results = srv.ntab.Lookup(target)
 }
 
 func (t *discoverTask) String() (s string) {
diff --git a/p2p/server.go b/p2p/server.go
index 59b97a0aa31870ded09e3dc1da23902a0aa0c50a..5eff70345fb0f58c240d054d82a4305cebbca9b8 100644
--- a/p2p/server.go
+++ b/p2p/server.go
@@ -115,6 +115,7 @@ type Server struct {
 	ntab         discoverTable
 	listener     net.Listener
 	ourHandshake *protoHandshake
+	lastLookup   time.Time
 
 	// These are for Peers, PeerCount (and nothing else).
 	peerOp     chan peerOpFunc