diff --git a/src/applications/calendar/query/PhabricatorCalendarEventQuery.php b/src/applications/calendar/query/PhabricatorCalendarEventQuery.php
index c66e36779..474ac49a4 100644
--- a/src/applications/calendar/query/PhabricatorCalendarEventQuery.php
+++ b/src/applications/calendar/query/PhabricatorCalendarEventQuery.php
@@ -1,179 +1,203 @@
 <?php
 
 final class PhabricatorCalendarEventQuery
   extends PhabricatorCursorPagedPolicyAwareQuery {
 
   private $ids;
   private $phids;
   private $rangeBegin;
   private $rangeEnd;
   private $inviteePHIDs;
   private $creatorPHIDs;
   private $isCancelled;
 
   public function withIDs(array $ids) {
     $this->ids = $ids;
     return $this;
   }
 
   public function withPHIDs(array $phids) {
     $this->phids = $phids;
     return $this;
   }
 
   public function withDateRange($begin, $end) {
     $this->rangeBegin = $begin;
     $this->rangeEnd = $end;
     return $this;
   }
 
   public function withInvitedPHIDs(array $phids) {
     $this->inviteePHIDs = $phids;
     return $this;
   }
 
   public function withCreatorPHIDs(array $phids) {
     $this->creatorPHIDs = $phids;
     return $this;
   }
 
   public function withIsCancelled($is_cancelled) {
     $this->isCancelled = $is_cancelled;
     return $this;
   }
 
+  protected function getDefaultOrderVector() {
+    return array('start', 'id');
+  }
+
+  public function getOrderableColumns() {
+    return array(
+      'start' => array(
+        'table' => $this->getPrimaryTableAlias(),
+        'column' => 'dateFrom',
+        'reverse' => true,
+        'type' => 'int',
+        'unique' => false,
+      ),
+    ) + parent::getOrderableColumns();
+  }
+
+  protected function getPagingValueMap($cursor, array $keys) {
+    $event = $this->loadCursorObject($cursor);
+    return array(
+      'start' => $event->getDateFrom(),
+      'id' => $event->getID(),
+    );
+  }
+
   protected function loadPage() {
     $table = new PhabricatorCalendarEvent();
     $conn_r = $table->establishConnection('r');
 
     $data = queryfx_all(
       $conn_r,
       'SELECT event.* FROM %T event %Q %Q %Q %Q %Q',
       $table->getTableName(),
       $this->buildJoinClause($conn_r),
       $this->buildWhereClause($conn_r),
       $this->buildGroupClause($conn_r),
       $this->buildOrderClause($conn_r),
       $this->buildLimitClause($conn_r));
 
     $events = $table->loadAllFromArray($data);
 
     foreach ($events as $event) {
       $event->applyViewerTimezone($this->getViewer());
     }
 
     return $events;
   }
 
   protected function buildJoinClauseParts(AphrontDatabaseConnection $conn_r) {
     $parts = parent::buildJoinClauseParts($conn_r);
     if ($this->inviteePHIDs !== null) {
       $parts[] = qsprintf(
         $conn_r,
         'JOIN %T invitee ON invitee.eventPHID = event.phid
           AND invitee.status != %s',
         id(new PhabricatorCalendarEventInvitee())->getTableName(),
         PhabricatorCalendarEventInvitee::STATUS_UNINVITED);
     }
     return $parts;
   }
 
   protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
     $where = array();
 
     if ($this->ids) {
       $where[] = qsprintf(
         $conn_r,
         'event.id IN (%Ld)',
         $this->ids);
     }
 
     if ($this->phids) {
       $where[] = qsprintf(
         $conn_r,
         'event.phid IN (%Ls)',
         $this->phids);
     }
 
     if ($this->rangeBegin) {
       $where[] = qsprintf(
         $conn_r,
         'event.dateTo >= %d',
         $this->rangeBegin);
     }
 
     if ($this->rangeEnd) {
       $where[] = qsprintf(
         $conn_r,
         'event.dateFrom <= %d',
         $this->rangeEnd);
     }
 
     if ($this->inviteePHIDs !== null) {
       $where[] = qsprintf(
         $conn_r,
         'invitee.inviteePHID IN (%Ls)',
         $this->inviteePHIDs);
     }
 
     if ($this->creatorPHIDs) {
       $where[] = qsprintf(
         $conn_r,
         'event.userPHID IN (%Ls)',
         $this->creatorPHIDs);
     }
 
     if ($this->isCancelled !== null) {
       $where[] = qsprintf(
         $conn_r,
         'event.isCancelled = %d',
         (int)$this->isCancelled);
     }
 
     $where[] = $this->buildPagingClause($conn_r);
 
     return $this->formatWhereClause($where);
   }
 
   protected function getPrimaryTableAlias() {
     return 'event';
   }
 
   protected function shouldGroupQueryResultRows() {
     if ($this->inviteePHIDs !== null) {
       return true;
     }
     return parent::shouldGroupQueryResultRows();
   }
 
   protected function getApplicationSearchObjectPHIDColumn() {
     return 'event.phid';
   }
 
   public function getQueryApplicationClass() {
     return 'PhabricatorCalendarApplication';
   }
 
 
   protected function willFilterPage(array $events) {
     $phids = array();
 
     foreach ($events as $event) {
       $phids[] = $event->getPHID();
     }
 
     $invitees = id(new PhabricatorCalendarEventInviteeQuery())
       ->setViewer($this->getViewer())
       ->withEventPHIDs($phids)
       ->execute();
     $invitees = mgroup($invitees, 'getEventPHID');
 
     foreach ($events as $event) {
       $event_invitees = idx($invitees, $event->getPHID(), array());
       $event->attachInvitees($event_invitees);
     }
 
     return $events;
   }
 
 }