diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index 127dcd825da..abd6120bf9d 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -1167,8 +1167,7 @@ pub(super) struct CurrentDepGraph<D: Deps> {
     /// ID from the previous session. In order to side-step this problem, we make
     /// sure that anonymous `NodeId`s allocated in different sessions don't overlap.
     /// This is implemented by mixing a session-key into the ID fingerprint of
-    /// each anon node. The session-key is just a random number generated when
-    /// the `DepGraph` is created.
+    /// each anon node. The session-key is a hash of the number of previous sessions.
     anon_id_seed: Fingerprint,
 
     /// These are simple counters that are for profiling and
@@ -1186,12 +1185,8 @@ impl<D: Deps> CurrentDepGraph<D> {
         record_stats: bool,
         previous: Arc<SerializedDepGraph>,
     ) -> Self {
-        use std::time::{SystemTime, UNIX_EPOCH};
-
-        let duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
-        let nanos = duration.as_nanos();
         let mut stable_hasher = StableHasher::new();
-        nanos.hash(&mut stable_hasher);
+        previous.session_count().hash(&mut stable_hasher);
         let anon_id_seed = stable_hasher.finish();
 
         #[cfg(debug_assertions)]
diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs
index 7750d6d1fef..9a639ede662 100644
--- a/compiler/rustc_query_system/src/dep_graph/serialized.rs
+++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs
@@ -92,6 +92,9 @@ pub struct SerializedDepGraph {
     /// Stores a map from fingerprints to nodes per dep node kind.
     /// This is the reciprocal of `nodes`.
     index: Vec<UnhashMap<PackedFingerprint, SerializedDepNodeIndex>>,
+    /// The number of previous compilation sessions. This is used to generate
+    /// unique anon dep nodes per session.
+    session_count: u64,
 }
 
 impl SerializedDepGraph {
@@ -146,6 +149,11 @@ impl SerializedDepGraph {
     pub fn node_count(&self) -> usize {
         self.nodes.len()
     }
+
+    #[inline]
+    pub fn session_count(&self) -> u64 {
+        self.session_count
+    }
 }
 
 /// A packed representation of an edge's start index and byte width.
@@ -252,6 +260,8 @@ impl SerializedDepGraph {
             .map(|_| UnhashMap::with_capacity_and_hasher(d.read_u32() as usize, Default::default()))
             .collect();
 
+        let session_count = d.read_u64();
+
         for (idx, node) in nodes.iter_enumerated() {
             if index[node.kind.as_usize()].insert(node.hash, idx).is_some() {
                 // Side effect nodes can have duplicates
@@ -273,6 +283,7 @@ impl SerializedDepGraph {
             edge_list_indices,
             edge_list_data,
             index,
+            session_count,
         })
     }
 }
@@ -601,7 +612,7 @@ impl<D: Deps> EncoderState<D> {
             stats: _,
             kind_stats,
             marker: _,
-            previous: _,
+            previous,
         } = self;
 
         let node_count = total_node_count.try_into().unwrap();
@@ -612,6 +623,8 @@ impl<D: Deps> EncoderState<D> {
             count.encode(&mut encoder);
         }
 
+        previous.session_count.checked_add(1).unwrap().encode(&mut encoder);
+
         debug!(?node_count, ?edge_count);
         debug!("position: {:?}", encoder.position());
         IntEncodedWithFixedSize(node_count).encode(&mut encoder);