Index: /trunk/downstream.go
===================================================================
--- /trunk/downstream.go	(revision 252)
+++ /trunk/downstream.go	(revision 253)
@@ -637,13 +637,4 @@
 		return err
 	}
-
-	// Only send history if we're the first connected client with that name and
-	// network
-	sendHistory := true
-	dc.user.forEachDownstream(func(conn *downstreamConn) {
-		if dc.clientName == conn.clientName && dc.network == conn.network {
-			sendHistory = false
-		}
-	})
 
 	dc.SendMessage(&irc.Message{
@@ -689,10 +680,30 @@
 
 	dc.forEachNetwork(func(net *network) {
-		seq, ok := net.history[dc.clientName]
-		if !sendHistory || !ok {
-			return
-		}
-
-		consumer := net.ring.NewConsumer(seq)
+		// Only send history if we're the first connected client with that name
+		// for the network
+		if _, ok := net.offlineClients[dc.clientName]; ok {
+			dc.sendNetworkHistory(net)
+			delete(net.offlineClients, dc.clientName)
+		}
+	})
+
+	return nil
+}
+
+func (dc *downstreamConn) sendNetworkHistory(net *network) {
+	for target, history := range net.history {
+		seq, ok := history.offlineClients[dc.clientName]
+		if !ok {
+			continue
+		}
+		delete(history.offlineClients, dc.clientName)
+
+		// If all clients have received history, no need to keep the
+		// ring buffer around
+		if len(history.offlineClients) == 0 {
+			delete(net.history, target)
+		}
+
+		consumer := history.ring.NewConsumer(seq)
 
 		// TODO: this means all history is lost when trying to send it while the
@@ -726,7 +737,5 @@
 			dc.SendMessage(dc.marshalMessage(msg, uc))
 		}
-	})
-
-	return nil
+	}
 }
 
Index: /trunk/upstream.go
===================================================================
--- /trunk/upstream.go	(revision 252)
+++ /trunk/upstream.go	(revision 253)
@@ -557,9 +557,9 @@
 				ch.Members[newNick] = membership
 				uc.appendLog(ch.Name, msg)
+				uc.appendHistory(ch.Name, msg)
 			}
 		}
 
 		if !me {
-			uc.network.ring.Produce(msg)
 			uc.forEachDownstream(func(dc *downstreamConn) {
 				dc.SendMessage(dc.marshalMessage(msg, uc))
@@ -663,9 +663,9 @@
 
 				uc.appendLog(ch.Name, msg)
+				uc.appendHistory(ch.Name, msg)
 			}
 		}
 
 		if msg.Prefix.Name != uc.nick {
-			uc.network.ring.Produce(msg)
 			uc.forEachDownstream(func(dc *downstreamConn) {
 				dc.SendMessage(dc.marshalMessage(msg, uc))
@@ -1295,4 +1295,27 @@
 }
 
+// appendHistory appends a message to the history. entity can be empty.
+func (uc *upstreamConn) appendHistory(entity string, msg *irc.Message) {
+	// If no client is offline, no need to append the message to the buffer
+	if len(uc.network.offlineClients) == 0 {
+		return
+	}
+
+	history, ok := uc.network.history[entity]
+	if !ok {
+		history = &networkHistory{
+			offlineClients: make(map[string]uint64),
+			ring:           NewRing(uc.srv.RingCap),
+		}
+		uc.network.history[entity] = history
+
+		for clientName, _ := range uc.network.offlineClients {
+			history.offlineClients[clientName] = 0
+		}
+	}
+
+	history.ring.Produce(msg)
+}
+
 // produce appends a message to the logs, adds it to the history and forwards
 // it to connected downstream connections.
@@ -1305,5 +1328,5 @@
 	}
 
-	uc.network.ring.Produce(msg)
+	uc.appendHistory(target, msg)
 
 	uc.forEachDownstream(func(dc *downstreamConn) {
Index: /trunk/user.go
===================================================================
--- /trunk/user.go	(revision 252)
+++ /trunk/user.go	(revision 253)
@@ -46,22 +46,27 @@
 }
 
+type networkHistory struct {
+	offlineClients map[string]uint64 // indexed by client name
+	ring           *Ring             // can be nil if there are no offline clients
+}
+
 type network struct {
 	Network
 	user    *user
-	ring    *Ring
 	stopped chan struct{}
 
-	conn      *upstreamConn
-	history   map[string]uint64
-	lastError error
+	conn           *upstreamConn
+	history        map[string]*networkHistory // indexed by entity
+	offlineClients map[string]struct{}        // indexed by client name
+	lastError      error
 }
 
 func newNetwork(user *user, record *Network) *network {
 	return &network{
-		Network: *record,
-		user:    user,
-		ring:    NewRing(user.srv.RingCap),
-		stopped: make(chan struct{}),
-		history: make(map[string]uint64),
+		Network:        *record,
+		user:           user,
+		stopped:        make(chan struct{}),
+		history:        make(map[string]*networkHistory),
+		offlineClients: make(map[string]struct{}),
 	}
 }
@@ -295,9 +300,4 @@
 			dc := e.dc
 
-			dc.forEachNetwork(func(net *network) {
-				seq := net.ring.Cur()
-				net.history[dc.clientName] = seq
-			})
-
 			for i := range u.downstreamConns {
 				if u.downstreamConns[i] == dc {
@@ -306,4 +306,23 @@
 				}
 			}
+
+			// Save history if we're the last client with this name
+			skipHistory := make(map[*network]bool)
+			u.forEachDownstream(func(conn *downstreamConn) {
+				if dc.clientName == conn.clientName {
+					skipHistory[conn.network] = true
+				}
+			})
+
+			dc.forEachNetwork(func(net *network) {
+				if skipHistory[net] || skipHistory[nil] {
+					return
+				}
+
+				net.offlineClients[dc.clientName] = struct{}{}
+				for _, history := range net.history {
+					history.offlineClients[dc.clientName] = history.ring.Cur()
+				}
+			})
 
 			u.forEachUpstream(func(uc *upstreamConn) {
