diff --git a/src/applications/differential/query/DifferentialDiffInlineCommentQuery.php b/src/applications/differential/query/DifferentialDiffInlineCommentQuery.php
--- a/src/applications/differential/query/DifferentialDiffInlineCommentQuery.php
+++ b/src/applications/differential/query/DifferentialDiffInlineCommentQuery.php
@@ -67,17 +67,26 @@
     return $id_map;
   }
 
+  protected function newInlineContextFromCacheData(array $map) {
+    return PhabricatorDiffInlineCommentContext::newFromCacheData($map);
+  }
+
   protected function newInlineContextMap(array $inlines) {
     $viewer = $this->getViewer();
-
     $map = array();
 
+    $changeset_ids = mpull($inlines, 'getChangesetID');
+
+    $changesets = id(new DifferentialChangesetQuery())
+      ->setViewer($viewer)
+      ->withIDs($changeset_ids)
+      ->needHunks(true)
+      ->execute();
+    $changesets = mpull($changesets, null, 'getID');
+
     foreach ($inlines as $key => $inline) {
-      $changeset = id(new DifferentialChangesetQuery())
-        ->setViewer($viewer)
-        ->withIDs(array($inline->getChangesetID()))
-        ->needHunks(true)
-        ->executeOne();
+      $changeset = idx($changesets, $inline->getChangesetID());
+
       if (!$changeset) {
         continue;
       }
diff --git a/src/applications/diffusion/query/DiffusionDiffInlineCommentQuery.php b/src/applications/diffusion/query/DiffusionDiffInlineCommentQuery.php
--- a/src/applications/diffusion/query/DiffusionDiffInlineCommentQuery.php
+++ b/src/applications/diffusion/query/DiffusionDiffInlineCommentQuery.php
@@ -70,4 +70,8 @@
     return array();
   }
 
+  protected function newInlineContextFromCacheData(array $map) {
+    return PhabricatorDiffInlineCommentContext::newFromCacheData($map);
+  }
+
 }
diff --git a/src/infrastructure/diff/inline/PhabricatorDiffInlineCommentContext.php b/src/infrastructure/diff/inline/PhabricatorDiffInlineCommentContext.php
--- a/src/infrastructure/diff/inline/PhabricatorDiffInlineCommentContext.php
+++ b/src/infrastructure/diff/inline/PhabricatorDiffInlineCommentContext.php
@@ -8,6 +8,26 @@
   private $bodyLines;
   private $tailLines;
 
+  public static function newFromCacheData(array $map) {
+    $context = new self();
+
+    $context->setFilename(idx($map, 'filename'));
+    $context->setHeadLines(idx($map, 'headLines'));
+    $context->setBodyLines(idx($map, 'bodyLines'));
+    $context->setTailLines(idx($map, 'tailLines'));
+
+    return $context;
+  }
+
+  public function newCacheDataMap() {
+    return array(
+      'filename' => $this->getFilename(),
+      'headLines' => $this->getHeadLines(),
+      'bodyLines' => $this->getBodyLines(),
+      'tailLines' => $this->getTailLines(),
+    );
+  }
+
   public function setFilename($filename) {
     $this->filename = $filename;
     return $this;
diff --git a/src/infrastructure/diff/interface/PhabricatorInlineComment.php b/src/infrastructure/diff/interface/PhabricatorInlineComment.php
--- a/src/infrastructure/diff/interface/PhabricatorInlineComment.php
+++ b/src/infrastructure/diff/interface/PhabricatorInlineComment.php
@@ -82,6 +82,16 @@
     return $this->storageObject;
   }
 
+  public function getInlineCommentCacheFragment() {
+    $phid = $this->getPHID();
+
+    if ($phid === null) {
+      return null;
+    }
+
+    return sprintf('inline(%s)', $phid);
+  }
+
   abstract protected function newStorageObject();
   abstract public function getControllerURI();
 
diff --git a/src/infrastructure/diff/query/PhabricatorDiffInlineCommentQuery.php b/src/infrastructure/diff/query/PhabricatorDiffInlineCommentQuery.php
--- a/src/infrastructure/diff/query/PhabricatorDiffInlineCommentQuery.php
+++ b/src/infrastructure/diff/query/PhabricatorDiffInlineCommentQuery.php
@@ -3,6 +3,8 @@
 abstract class PhabricatorDiffInlineCommentQuery
   extends PhabricatorApplicationTransactionCommentQuery {
 
+  const INLINE_CONTEXT_CACHE_VERSION = 1;
+
   private $fixedStates;
   private $needReplyToComments;
   private $publishedComments;
@@ -19,6 +21,7 @@
     array $comments);
 
   abstract protected function newInlineContextMap(array $inlines);
+  abstract protected function newInlineContextFromCacheData(array $map);
 
   final public function withFixedStates(array $states) {
     $this->fixedStates = $states;
@@ -268,16 +271,83 @@
       }
 
       if ($need_context) {
-        $context_map = $this->newInlineContextMap($need_context);
+        $this->loadInlineCommentContext($need_context);
+      }
+    }
+
+    return $inlines;
+  }
+
+  private function loadInlineCommentContext(array $inlines) {
+    $cache_keys = array();
+    foreach ($inlines as $key => $inline) {
+      $object = $inline->newInlineCommentObject();
+      $fragment = $object->getInlineCommentCacheFragment();
+
+      if ($fragment === null) {
+        continue;
+      }
+
+      $cache_keys[$key] = sprintf(
+        '%s.context(v%d)',
+        $fragment,
+        self::INLINE_CONTEXT_CACHE_VERSION);
+    }
+
+    $cache = PhabricatorCaches::getMutableStructureCache();
+
+    $cache_map = $cache->getKeys($cache_keys);
+
+    $context_map = array();
+    $need_construct = array();
+
+    foreach ($inlines as $key => $inline) {
+      $cache_key = idx($cache_keys, $key);
 
-        foreach ($need_context as $key => $inline) {
-          $inline->attachInlineContext(idx($context_map, $key));
+      if ($cache_key !== null) {
+        if (array_key_exists($cache_key, $cache_map)) {
+          $cache_data = $cache_map[$cache_key];
+          $context_map[$key] = $this->newInlineContextFromCacheData(
+            $cache_data);
+          continue;
         }
       }
 
+      $need_construct[$key] = $inline;
     }
 
-    return $inlines;
+    if ($need_construct) {
+      $construct_map = $this->newInlineContextMap($need_construct);
+
+      $write_map = array();
+      foreach ($construct_map as $key => $context) {
+        if ($context === null) {
+          $cache_data = $context;
+        } else {
+          $cache_data = $this->newCacheDataFromInlineContext($context);
+        }
+
+        $cache_key = idx($cache_keys, $key);
+        if ($cache_key !== null) {
+          $write_map[$cache_key] = $cache_data;
+        }
+      }
+
+      if ($write_map) {
+        $cache->setKeys($write_map);
+      }
+
+      $context_map += $construct_map;
+    }
+
+    foreach ($inlines as $key => $inline) {
+      $inline->attachInlineContext(idx($context_map, $key));
+    }
+  }
+
+  protected function newCacheDataFromInlineContext(
+    PhabricatorInlineCommentContext $context) {
+    return $context->newCacheDataMap();
   }
 
   final protected function simplifyContext(array $lines, $is_head) {