diff --git a/src/applications/differential/controller/DifferentialChangesetViewController.php b/src/applications/differential/controller/DifferentialChangesetViewController.php
--- a/src/applications/differential/controller/DifferentialChangesetViewController.php
+++ b/src/applications/differential/controller/DifferentialChangesetViewController.php
@@ -251,15 +251,19 @@
       ->setMask($mask);
 
     if ($request->isAjax()) {
+      // NOTE: We must render the changeset before we render coverage
+      // information, since it builds some caches.
+      $rendered_changeset = $parser->renderChangeset();
+
       $mcov = $parser->renderModifiedCoverage();
 
-      $coverage = array(
+      $coverage_data = array(
         'differential-mcoverage-'.md5($changeset->getFilename()) => $mcov,
       );
 
       return id(new PhabricatorChangesetResponse())
-        ->setRenderedChangeset($parser->renderChangeset())
-        ->setCoverage($coverage)
+        ->setRenderedChangeset($rendered_changeset)
+        ->setCoverage($coverage_data)
         ->setUndoTemplates($parser->getRenderer()->renderUndoTemplates());
     }
 
diff --git a/src/applications/differential/controller/DifferentialDiffViewController.php b/src/applications/differential/controller/DifferentialDiffViewController.php
--- a/src/applications/differential/controller/DifferentialDiffViewController.php
+++ b/src/applications/differential/controller/DifferentialDiffViewController.php
@@ -108,7 +108,7 @@
     $table_of_contents = id(new DifferentialDiffTableOfContentsView())
       ->setChangesets($changesets)
       ->setVisibleChangesets($changesets)
-      ->setUnitTestData(idx($props, 'arc:unit', array()));
+      ->setCoverageMap($diff->loadCoverageMap($viewer));
 
     $refs = array();
     foreach ($changesets as $changeset) {
diff --git a/src/applications/differential/controller/DifferentialRevisionViewController.php b/src/applications/differential/controller/DifferentialRevisionViewController.php
--- a/src/applications/differential/controller/DifferentialRevisionViewController.php
+++ b/src/applications/differential/controller/DifferentialRevisionViewController.php
@@ -353,7 +353,7 @@
     $toc_view->setChangesets($changesets);
     $toc_view->setVisibleChangesets($visible_changesets);
     $toc_view->setRenderingReferences($rendering_references);
-    $toc_view->setUnitTestData(idx($props, 'arc:unit', array()));
+    $toc_view->setCoverageMap($target->loadCoverageMap($user));
     if ($repository) {
       $toc_view->setRepository($repository);
     }
diff --git a/src/applications/differential/storage/DifferentialDiff.php b/src/applications/differential/storage/DifferentialDiff.php
--- a/src/applications/differential/storage/DifferentialDiff.php
+++ b/src/applications/differential/storage/DifferentialDiff.php
@@ -348,6 +348,31 @@
     return $target_phids;
   }
 
+  public function loadCoverageMap(PhabricatorUser $viewer) {
+    $target_phids = $this->getBuildTargetPHIDs();
+    if (!$target_phids) {
+      return array();
+    }
+
+    $unit = id(new HarbormasterBuildUnitMessage())->loadAllWhere(
+      'buildTargetPHID IN (%Ls)',
+      $target_phids);
+
+    $map = array();
+    foreach ($unit as $message) {
+      $coverage = $message->getProperty('coverage', array());
+      foreach ($coverage as $path => $coverage_data) {
+        $map[$path][] = $coverage_data;
+      }
+    }
+
+    foreach ($map as $path => $coverage_items) {
+      $map[$path] = ArcanistUnitTestResult::mergeCoverage($coverage_items);
+    }
+
+    return $map;
+  }
+
 /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 
 
diff --git a/src/applications/differential/view/DifferentialDiffTableOfContentsView.php b/src/applications/differential/view/DifferentialDiffTableOfContentsView.php
--- a/src/applications/differential/view/DifferentialDiffTableOfContentsView.php
+++ b/src/applications/differential/view/DifferentialDiffTableOfContentsView.php
@@ -10,7 +10,7 @@
   private $renderURI = '/differential/changeset/';
   private $revisionID;
   private $whitespace;
-  private $unitTestData;
+  private $coverageMap;
 
   public function setChangesets($changesets) {
     $this->changesets = $changesets;
@@ -37,8 +37,8 @@
     return $this;
   }
 
-  public function setUnitTestData($unit_test_data) {
-    $this->unitTestData = $unit_test_data;
+  public function setCoverageMap(array $coverage_map) {
+    $this->coverageMap = $coverage_map;
     return $this;
   }
 
@@ -60,23 +60,6 @@
 
     $rows = array();
 
-    $coverage = array();
-    if ($this->unitTestData) {
-      $coverage_by_file = array();
-      foreach ($this->unitTestData as $result) {
-        $test_coverage = idx($result, 'coverage');
-        if (!$test_coverage) {
-          continue;
-        }
-        foreach ($test_coverage as $file => $results) {
-          $coverage_by_file[$file][] = $results;
-        }
-      }
-      foreach ($coverage_by_file as $file => $coverages) {
-        $coverage[$file] = ArcanistUnitTestResult::mergeCoverage($coverages);
-      }
-    }
-
     $changesets = $this->changesets;
     $paths = array();
     foreach ($changesets as $id => $changeset) {
@@ -144,7 +127,7 @@
             'M');
 
       $fname = $changeset->getFilename();
-      $cov  = $this->renderCoverage($coverage, $fname);
+      $cov  = $this->renderCoverage($this->coverageMap, $fname);
       if ($cov === null) {
         $mcov = $cov = phutil_tag('em', array(), '-');
       } else {