diff --git a/doc/dev-notes.txt b/doc/dev-notes.txt
index 5b1bed15..b1fef80d 100644
--- a/doc/dev-notes.txt
+++ b/doc/dev-notes.txt
@@ -129,3 +129,13 @@
 
   $ nix-env -p /nix/var/nix/profiles/per-user/eelco/hydra-deps -f deps.nix -i \* --arg pkgs 'import /home/eelco/Dev/nixpkgs {}'
   
+
+* select x.project, x.jobset, x.job, x.system, x.id, x.timestamp, r.buildstatus, b.id, b.timestamp
+  from (select project, jobset, job, system, max(id) as id from Builds where finished = 1 group by project, jobset, job, system) as a_
+  natural join Builds x
+  natural join BuildResultInfo r
+  left join Builds b on b.id =
+    (select max(id) from builds c
+     natural join buildresultinfo r2
+     where x.project = c.project and x.jobset = c.jobset and x.job = c.job and x.system = c.system
+           and x.id > c.id and r.buildstatus != r2.buildstatus);
diff --git a/src/lib/Hydra/Base/Controller/ListBuilds.pm b/src/lib/Hydra/Base/Controller/ListBuilds.pm
index ec5abdf5..2390cffc 100644
--- a/src/lib/Hydra/Base/Controller/ListBuilds.pm
+++ b/src/lib/Hydra/Base/Controller/ListBuilds.pm
@@ -14,7 +14,7 @@ sub filterInactiveJobs {
         { join => 'job'
         , '+select' => ["job.active"]
         , '+as' => ["active"]
-        })
+        });
 }
 
 
@@ -26,6 +26,13 @@ sub getJobStatus {
     $latest = filterInactiveJobs($latest)
         unless defined $c->stash->{showInactiveJobs};
 
+    $latest = $latest->search(
+        {},
+        { '+select' => ["me.statusChangeId", "me.statusChangeTime"]
+        , '+as' => ["statusChangeId", "statusChangeTime"]
+        , order_by => "statusChangeTime DESC"
+        });
+
     return $latest;
 }
 
@@ -49,7 +56,7 @@ sub errors : Chained('get_builds') PathPart Args(0) {
         [$c->stash->{allJobs}->search({errormsg => {'!=' => ''}})]
         if defined $c->stash->{allJobs};
     $c->stash->{brokenBuilds} =
-        [getJobStatus($self, $c)->search({buildstatus => {'!=' => 0}})];
+        [getJobStatus($self, $c)->search({'me.buildstatus' => {'!=' => 0}})];
 }
 
     
diff --git a/src/lib/Hydra/Schema/Builds.pm b/src/lib/Hydra/Schema/Builds.pm
index c78e649b..83c1b8e0 100644
--- a/src/lib/Hydra/Schema/Builds.pm
+++ b/src/lib/Hydra/Schema/Builds.pm
@@ -193,10 +193,10 @@ __PACKAGE__->belongs_to(
 );
 
 sub addSequence {
-   my $hydradbi = getHydraDBPath ;
-   if ($hydradbi =~ m/^dbi:Pg/) {
-      __PACKAGE__->sequence('builds_id_seq');
-  }
+    my $hydradbi = getHydraDBPath;
+    if ($hydradbi =~ m/^dbi:Pg/) {
+        __PACKAGE__->sequence('builds_id_seq');
+    }
 }
 
 sub makeSource {
@@ -210,8 +210,14 @@ sub makeSource {
 
 sub makeQueries {
     my ($name, $constraint) = @_;
-    makeSource('JobStatus' . $name, "select * from (select project, jobset, job, system, max(id) as id from Builds where finished = 1 $constraint group by project, jobset, job, system) as a natural join Builds");
-    makeSource('LatestSucceeded' . $name, "select * from (select project, jobset, job, system, max(id) as id from Builds natural join BuildResultInfo where finished = 1 and buildStatus = 0 $constraint group by project, jobset, job, system) as a natural join Builds");
+    my $joinWithStatusChange =
+        "natural join BuildResultInfo r " .
+        "left join Builds b on b.id = " .
+        "(select max(id) from builds c natural join buildresultinfo r2 " .
+        "  where x.project = c.project and x.jobset = c.jobset and x.job = c.job and x.system = c.system and " .
+        "    x.id > c.id and r.buildstatus != r2.buildstatus)";
+    makeSource('JobStatus' . $name, "select *, b.id statusChangeId, b.timestamp statusChangeTime from (select project, jobset, job, system, max(id) as id from Builds where finished = 1 $constraint group by project, jobset, job, system) as latest natural join Builds x $joinWithStatusChange");
+    makeSource('LatestSucceeded' . $name, "select * from (select project, jobset, job, system, max(id) as id from Builds natural join BuildResultInfo where finished = 1 and buildStatus = 0 $constraint group by project, jobset, job, system) as latest natural join Builds x $joinWithStatusChange");
 }
 
 addSequence;
diff --git a/src/root/common.tt b/src/root/common.tt
index 58fcad64..10fe1609 100644
--- a/src/root/common.tt
+++ b/src/root/common.tt
@@ -73,6 +73,9 @@
         <th>Release Name</th>
         <th>System</th>
         <th>Timestamp</th>
+        [% IF showStatusChange %]
+          <th class="headerSortUp">Last status change</th>
+        [% END %]
         <th>Description</th>
       </tr>
     </thead>
@@ -105,6 +108,17 @@
           <td>[% !showSchedulingInfo and build.get_column('releasename') ? build.get_column('releasename') : build.nixname %]</td>
           <td><tt>[% build.system %]</tt></td>
           <td>[% date.format(build.timestamp, '%Y-%m-%d %H:%M:%S') %]</td>
+          [% IF showStatusChange %]
+          <td>
+            [% IF build.get_column('statusChangeTime') %]
+              <a href="[% c.uri_for('/build' build.get_column('statusChangeId')) %]">
+                [% date.format(build.get_column('statusChangeTime'), '%Y-%m-%d %H:%M:%S') %]
+              </a>
+            [% ELSE %]
+              <em>never</em>
+            [% END %]
+          </td>
+          [% END %]
           <td>[% build.description %]</td>
         </tr>
       [% END -%]
diff --git a/src/root/errors.tt b/src/root/errors.tt
index 2dc6e00f..abf14a3f 100644
--- a/src/root/errors.tt
+++ b/src/root/errors.tt
@@ -67,7 +67,7 @@ that don’t build.</p>
 
 <h2>Broken builds</h2>
 
-[% INCLUDE renderBuildList builds=brokenBuilds %]
+[% INCLUDE renderBuildList builds=brokenBuilds showStatusChange=1 %]
 
 [% END %]
 
diff --git a/src/root/jobstatus.tt b/src/root/jobstatus.tt
index b6a6c060..ab10a36b 100644
--- a/src/root/jobstatus.tt
+++ b/src/root/jobstatus.tt
@@ -3,8 +3,11 @@
 
 <h1>Job Status[% IF project %] of Project <tt>[% project.name %]</tt>[% END %]</h1>
 
-<p>Below are the latest builds for each job.</p>
+<p>Below are the latest builds for each job.  It is ordered by the status
+change time (the timestamp of the last build that had a different
+build result status).  That is, it shows the jobs that most recently
+changed from failed to successful or vice versa first.</p>
 
-[% INCLUDE renderBuildList builds=latestBuilds %]
+[% INCLUDE renderBuildList builds=latestBuilds showStatusChange=1 %]
 
 [% END %]
diff --git a/src/sql/hydra.sql b/src/sql/hydra.sql
index 57a6ac70..8183770e 100644
--- a/src/sql/hydra.sql
+++ b/src/sql/hydra.sql
@@ -407,4 +407,5 @@ create table ReleaseSetJobs (
 create index IndexBuildInputsByBuild on BuildInputs(build);
 create index IndexBuildInputsByDependency on BuildInputs(dependency);
 create index IndexBuildsByTimestamp on Builds(timestamp);
---create index IndexBuildsByJobAndSystem on Builds(project, jobset, job, system);
+create index IndexBuildsByJobAndSystem on Builds(project, jobset, job, system);
+create index IndexBuildResultInfo on BuildResultInfo(id); -- primary key index, not created automatically by PostgreSQL