diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -513,6 +513,7 @@
     'Future' => 'future/Future.php',
     'FutureIterator' => 'future/FutureIterator.php',
     'FutureIteratorTestCase' => 'future/__tests__/FutureIteratorTestCase.php',
+    'FuturePool' => 'future/FuturePool.php',
     'FutureProxy' => 'future/FutureProxy.php',
     'HTTPFuture' => 'future/http/HTTPFuture.php',
     'HTTPFutureCURLResponseStatus' => 'future/http/status/HTTPFutureCURLResponseStatus.php',
@@ -1455,6 +1456,7 @@
       'Iterator',
     ),
     'FutureIteratorTestCase' => 'PhutilTestCase',
+    'FuturePool' => 'Phobject',
     'FutureProxy' => 'Future',
     'HTTPFuture' => 'BaseHTTPFuture',
     'HTTPFutureCURLResponseStatus' => 'HTTPFutureResponseStatus',
diff --git a/src/future/FuturePool.php b/src/future/FuturePool.php
new file mode 100644
--- /dev/null
+++ b/src/future/FuturePool.php
@@ -0,0 +1,67 @@
+<?php
+
+final class FuturePool
+  extends Phobject {
+
+  private $shouldRewind;
+  private $iteratorTemplate;
+  private $iterator;
+  private $futures = array();
+
+  public function __construct() {
+    $this->iteratorTemplate = new FutureIterator(array());
+  }
+
+  public function getIteratorTemplate() {
+    return $this->iteratorTemplate;
+  }
+
+  public function addFuture(Future $future) {
+    $future_key = $future->getFutureKey();
+
+    if (!isset($this->futures[$future_key])) {
+      if (!$this->iterator) {
+        $this->iterator = clone $this->getIteratorTemplate();
+        $this->shouldRewind = true;
+      }
+
+      $iterator = $this->iterator;
+      $iterator->addFuture($future);
+
+      $this->futures[$future_key] = $future;
+    }
+
+    return $this;
+  }
+
+  public function hasFutures() {
+    return (bool)$this->futures;
+  }
+
+  public function resolve() {
+    $iterator = $this->iterator;
+
+    if (!$iterator) {
+      return null;
+    }
+
+    if ($this->shouldRewind) {
+      $iterator->rewind();
+      $this->shouldRewind = false;
+    } else {
+      $iterator->next();
+    }
+
+    if ($iterator->valid()) {
+      $future_key = $iterator->key();
+      if ($future_key !== null) {
+        unset($this->futures[$future_key]);
+      }
+      return $iterator->current();
+    } else {
+      $this->iterator = null;
+      return null;
+    }
+  }
+
+}