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
@@ -34,6 +34,7 @@
     'AphrontObjectMissingQueryException' => 'aphront/storage/exception/AphrontObjectMissingQueryException.php',
     'AphrontParameterQueryException' => 'aphront/storage/exception/AphrontParameterQueryException.php',
     'AphrontQueryException' => 'aphront/storage/exception/AphrontQueryException.php',
+    'AphrontQueryTimeoutQueryException' => 'aphront/storage/exception/AphrontQueryTimeoutQueryException.php',
     'AphrontRecoverableQueryException' => 'aphront/storage/exception/AphrontRecoverableQueryException.php',
     'AphrontRequestStream' => 'aphront/requeststream/AphrontRequestStream.php',
     'AphrontSchemaQueryException' => 'aphront/storage/exception/AphrontSchemaQueryException.php',
@@ -564,6 +565,7 @@
     'AphrontObjectMissingQueryException' => 'AphrontQueryException',
     'AphrontParameterQueryException' => 'AphrontQueryException',
     'AphrontQueryException' => 'Exception',
+    'AphrontQueryTimeoutQueryException' => 'AphrontRecoverableQueryException',
     'AphrontRecoverableQueryException' => 'AphrontQueryException',
     'AphrontRequestStream' => 'Phobject',
     'AphrontSchemaQueryException' => 'AphrontQueryException',
diff --git a/src/aphront/storage/connection/AphrontDatabaseConnection.php b/src/aphront/storage/connection/AphrontDatabaseConnection.php
--- a/src/aphront/storage/connection/AphrontDatabaseConnection.php
+++ b/src/aphront/storage/connection/AphrontDatabaseConnection.php
@@ -9,6 +9,7 @@
 
   private $transactionState;
   private $readOnly;
+  private $queryTimeout;
 
   abstract public function getInsertID();
   abstract public function getAffectedRows();
@@ -48,6 +49,15 @@
     return $this->readOnly;
   }
 
+  public function setQueryTimeout($query_timeout) {
+    $this->queryTimeout = $query_timeout;
+    return $this;
+  }
+
+  public function getQueryTimeout() {
+    return $this->queryTimeout;
+  }
+
   public function asyncQuery($raw_query) {
     throw new Exception(pht('Async queries are not supported.'));
   }
diff --git a/src/aphront/storage/connection/mysql/AphrontMySQLiDatabaseConnection.php b/src/aphront/storage/connection/mysql/AphrontMySQLiDatabaseConnection.php
--- a/src/aphront/storage/connection/mysql/AphrontMySQLiDatabaseConnection.php
+++ b/src/aphront/storage/connection/mysql/AphrontMySQLiDatabaseConnection.php
@@ -81,7 +81,37 @@
   }
 
   protected function rawQuery($raw_query) {
-    return @$this->requireConnection()->query($raw_query);
+    $conn = $this->requireConnection();
+    $time_limit = $this->getQueryTimeout();
+
+    // If we have a query time limit, run this query synchronously but use
+    // the async API. This allows us to kill queries which take too long
+    // without requiring any configuration on the server side.
+    if ($time_limit && $this->supportsAsyncQueries()) {
+      $conn->query($raw_query, MYSQLI_ASYNC);
+
+      $read = array($conn);
+      $error = array($conn);
+      $reject = array($conn);
+
+      $result = mysqli::poll($read, $error, $reject, $time_limit);
+
+      if ($result === false) {
+        $this->closeConnection();
+        throw new Exception(
+          pht('Failed to poll mysqli connection!'));
+      } else if ($result === 0) {
+        $this->closeConnection();
+        throw new AphrontQueryTimeoutQueryException(
+          pht(
+            'Query timed out after %s second(s)!',
+            new PhutilNumber($time_limit)));
+      }
+
+      return @$conn->reap_async_query();
+    }
+
+    return @$conn->query($raw_query);
   }
 
   protected function rawQueries(array $raw_queries) {
diff --git a/src/aphront/storage/exception/AphrontQueryTimeoutQueryException.php b/src/aphront/storage/exception/AphrontQueryTimeoutQueryException.php
new file mode 100644
--- /dev/null
+++ b/src/aphront/storage/exception/AphrontQueryTimeoutQueryException.php
@@ -0,0 +1,4 @@
+<?php
+
+final class AphrontQueryTimeoutQueryException
+  extends AphrontRecoverableQueryException {}