diff --git a/buildstream/_scheduler/queues/buildqueue.py b/buildstream/_scheduler/queues/buildqueue.py
index 66ec4c69b9a0f1090ed668392be56a62f351bf8d..c8ac3f7fdbbeadde3491d173850a837dcd10e2b6 100644
--- a/buildstream/_scheduler/queues/buildqueue.py
+++ b/buildstream/_scheduler/queues/buildqueue.py
@@ -70,9 +70,6 @@ class BuildQueue(Queue):
         return element._assemble()
 
     def status(self, element):
-        # state of dependencies may have changed, recalculate element state
-        element._update_state()
-
         if not element._is_required():
             # Artifact is not currently required but it may be requested later.
             # Keep it in the queue.
diff --git a/buildstream/_scheduler/queues/fetchqueue.py b/buildstream/_scheduler/queues/fetchqueue.py
index fc11fd1d19f21540bfab9a75e71b37972d3fb85b..31aa6001d041909aade1956fd14a9f28e6a36ef9 100644
--- a/buildstream/_scheduler/queues/fetchqueue.py
+++ b/buildstream/_scheduler/queues/fetchqueue.py
@@ -44,9 +44,6 @@ class FetchQueue(Queue):
         element._fetch()
 
     def status(self, element):
-        # state of dependencies may have changed, recalculate element state
-        element._update_state()
-
         if not element._is_required():
             # Artifact is not currently required but it may be requested later.
             # Keep it in the queue.
diff --git a/buildstream/_scheduler/queues/pullqueue.py b/buildstream/_scheduler/queues/pullqueue.py
index dbeb806e54038884241d42629e24a122965754aa..013ee64890dcfd1e9d1f6022626e4763e9fba24a 100644
--- a/buildstream/_scheduler/queues/pullqueue.py
+++ b/buildstream/_scheduler/queues/pullqueue.py
@@ -39,9 +39,6 @@ class PullQueue(Queue):
             raise SkipJob(self.action_name)
 
     def status(self, element):
-        # state of dependencies may have changed, recalculate element state
-        element._update_state()
-
         if not element._is_required():
             # Artifact is not currently required but it may be requested later.
             # Keep it in the queue.
diff --git a/buildstream/element.py b/buildstream/element.py
index 89e3014c52cde6203c5651bd66b0a051f1d045b6..578ed6a4f35b483577a998d31770a47237bccf1e 100644
--- a/buildstream/element.py
+++ b/buildstream/element.py
@@ -197,6 +197,7 @@ class Element(Plugin):
 
         self.__runtime_dependencies = []        # Direct runtime dependency Elements
         self.__build_dependencies = []          # Direct build dependency Elements
+        self.__reverse_build_dependencies = []  # Direct reverse dependency Elements
         self.__sources = []                     # List of Sources
         self.__weak_cache_key = None            # Our cached weak cache key
         self.__strict_cache_key = None          # Our cached cache key for strict builds
@@ -439,6 +440,21 @@ class Element(Plugin):
         if should_yield and (recurse or recursed) and scope != Scope.BUILD:
             yield self
 
+    def reverse_build_dependencies(self):
+        """Get all reverse dependencies for the given element in a topological order.
+
+        Currently, dependencies might be returned multiple times.
+        """
+        # FIXME: we should return each entry only once in topological order
+        def recurse_rdeps(element):
+            yield element
+
+            for rdep in element.__reverse_build_dependencies:
+                yield from recurse_rdeps(rdep)
+
+        for rdep in self.__reverse_build_dependencies:
+            yield from recurse_rdeps(rdep)
+
     def search(self, scope, name):
         """Search for a dependency by name
 
@@ -930,6 +946,7 @@ class Element(Plugin):
         for meta_dep in meta.build_dependencies:
             dependency = Element._new_from_meta(meta_dep)
             element.__build_dependencies.append(dependency)
+            dependency.__reverse_build_dependencies.append(element)
 
         return element
 
@@ -1306,6 +1323,9 @@ class Element(Plugin):
 
         self._update_state()
 
+        for reverse_dep in self.reverse_build_dependencies():
+            reverse_dep._update_state()
+
     # _track():
     #
     # Calls track() on the Element sources
@@ -1500,6 +1520,9 @@ class Element(Plugin):
         self._update_state()
 
         if self._get_workspace() and self._cached_success():
+            for rdep in self.reverse_build_dependencies():
+                rdep._update_state()
+
             assert utils._is_main_process(), \
                 "Attempted to save workspace configuration from child process"
             #