diff --git a/configure.ac b/configure.ac
index 3896778f0ed8c90b412995fa48fe912220af5af3..b928ae1ab7f4e38292db82790f187feb352c1883 100644
--- a/configure.ac
+++ b/configure.ac
@@ -100,11 +100,23 @@ if test "$enable_san" = "yes"; then
    fi
 fi
 
+
 # Autoconf stuff
 AC_PROG_INSTALL
 AC_PROG_MAKE_SET
 AC_HEADER_STDC
 
+AC_ARG_ENABLE([task-timers],
+   [AS_HELP_STRING([--enable-task-timers],
+      [Enables task timer output and collection of extra data to enable it])],
+    [enable_tts="$enableval"],
+    [enable_tts="no"]
+)
+
+if test "$enable_tts" = "yes"; then
+  AC_DEFINE(WITH_TASK_TIMERS,1,[Define if Task Timer recording is enabled])
+fi
+
 # Check for pthreads.
 AX_PTHREAD([LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
     CC="$PTHREAD_CC" LDFLAGS="$LDFLAGS $PTHREAD_LIBS $LIBS"]
diff --git a/examples/plot_tasks.py b/examples/plot_tasks.py
new file mode 100644
index 0000000000000000000000000000000000000000..84a09524665a6c0935648eb728b7d9447982343a
--- /dev/null
+++ b/examples/plot_tasks.py
@@ -0,0 +1,155 @@
+#!/usr/bin/env python
+
+"""
+Usage:
+  plot_tasks.py TASKTIMERS output.png [Ticks per ms]
+  
+  where TASKTIMERS is a task timers file generated by quicksched.
+  
+  This file is part of QuickSched.
+  Copyright (c) 2017 Aidan Chalk (aidan.chalk@stfc.ac.uk)
+  
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published
+by the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+import matplotlib
+import matplotlib.pyplot as plt
+import matplotlib.colors as colors
+import matplotlib.collections as collections
+import matplotlib.cm as cmx
+import matplotlib.gridspec as gridspec
+matplotlib.use('Agg')
+import pylab as pl
+import numpy as np
+import sys
+import math
+
+#  Basic plot configuration.
+PLOT_PARAMS = {"axes.labelsize": 10,
+               "axes.titlesize": 10,
+               "font.size": 14,
+               "legend.fontsize": 12,
+               "xtick.labelsize": 11,
+               "ytick.labelsize": 11,
+               "figure.figsize" : (16., 4.),
+               "figure.subplot.left" : 0.03,
+               "figure.subplot.right" : 0.995,
+               "figure.subplot.bottom" : 0.1,
+               "figure.subplot.top" : 0.99,
+               "figure.subplot.wspace" : 0.,
+               "figure.subplot.hspace" : 0.,
+               "lines.markersize" : 6,
+               "lines.linewidth" : 3.
+               }
+               
+TASKCOLOURS = ["black",
+               "lightblue",
+               "greenyellow",
+               "navy",
+               "greenyellow",
+               "navy",
+               "indigo",
+               "cyan",
+               "cyan",
+               "green",
+               "yellow",
+               "magenta",
+               "mediumorchid",
+               #"mediumnightblue",
+               "mediumturquoise",
+               "mediumvioletred",
+               "darkred",
+               "darkblue"
+               #,"powerblue"
+               ]
+               
+pl.rcParams.update(PLOT_PARAMS)
+
+if len(sys.argv) == 2 and (sys.argv[1][0:2] == "-h" or sys.argv[1][0:3] == "--h"):
+    from pydoc import help
+    help( "__main__")
+    sys.exit(0)
+
+#Input from command line
+if len(sys.argv) != 3 and len(sys.argv) != 4:
+    print "Usage: ", sys.argv[0], "TASKTIMERS output.png [ticks-per-ms]"
+    sys.exit(1)
+    
+
+    
+infile = sys.argv[1]
+outpng = sys.argv[2]
+tpms = 0
+if len(sys.argv) == 4:
+    tpms = int(sys.argv[3])
+    
+#read input.
+data = pl.loadtxt(infile)
+nthread=int(max(data[:,1])) + 1
+
+#Recompute timings in MS if possible.
+if(tpms != 0):
+    data[:,2] = data[:,2] / tpms
+    data[:,3] = data[:,3] / tpms
+    
+start_t = min(data[:,2])
+data[:,2] -= start_t
+data[:,3] -= start_t
+end_t = (max(data[:,3]))
+start_t = min(data[:,2])
+delta_t = end_t - start_t
+
+
+
+fig = pl.figure()
+ax = fig.add_subplot(1,1,1)
+ax.set_xlim(-delta_t * 0.03, delta_t * 1.03)
+ax.set_ylim(0, nthread)
+
+print len(data[:,0])
+
+for j in range(nthread):
+    tictocs = np.zeros(len(data[:,0])*2) 
+    types = np.zeros(len(data[:,0])*2) 
+    for i in range(len(data[:,0])):
+        if data[i,1] == j:
+            tictocs[i*2+0] = data[i,2]
+            tictocs[i*2+1] = data[i,3]
+            types[i*2+0] = int(data[i,0])
+            types[i*2+1] = int(data[i,0])
+        #print tictocs
+        #print data[i,1]+0.05
+        
+    for i in range(len(TASKCOLOURS)):
+        print i
+        print types==i
+        collection = collections.BrokenBarHCollection.span_where(tictocs, ymin=j+0.05, ymax=j+0.95, where=types==i, facecolor=TASKCOLOURS[i], linewidths=1, edgecolor="white")
+        ax.add_collection(collection)
+    
+# Start and end of time-step
+ax.plot([start_t, start_t], [0, nthread], 'k--', linewidth=1)
+ax.plot([end_t, end_t], [0, nthread], 'k--', linewidth=1)
+
+ax.set_xlabel("time [ms or ticks]")
+ax.set_ylabel("Thread ID" )
+ax.set_yticks(pl.array(range(nthread)), True)
+
+pl.savefig(outpng, format = 'png', dpi = 1000)
+pl.savefig('tasks.eps', format = 'eps', dpi = 1000)
+
+pl.show()
+
+print "Graphics done, output written to", outpng
+
+sys.exit(0)
diff --git a/src/qsched.c b/src/qsched.c
index 75286d3bd62ec33575578fa7d0921850613aabb9..91aeafe740f8642e104ff415aeebc197dd535f71 100644
--- a/src/qsched.c
+++ b/src/qsched.c
@@ -627,6 +627,9 @@ void qsched_done ( struct qsched *s , struct task *t ) {
     
     /* Set the task stats. */
     t->toc = getticks();
+    #ifdef WITH_TASK_TIMERS
+    t->tid = omp_get_thread_num();
+    #endif
     if (!(s->flags & qsched_flag_norecost))
         t->cost = t->toc - t->tic;
 
@@ -1687,3 +1690,24 @@ void f_qsched_destroy( struct qsched *s)
     free(s);
 }
 
+
+void qsched_dump_task_timers( struct qsched *s, char *filename ){
+#ifdef WITH_TASK_TIMERS
+FILE *task_file;
+
+task_file = fopen(filename, "w");
+
+for(int i = 0; i < s->count; i++)
+{
+    struct task *t = &s->tasks[i];
+    
+    fprintf(task_file,"%i %i %lli %lli\n", t->type, t->tid, t->tic, t->toc);
+
+}
+
+
+fclose(task_file);
+#else
+error("Quicksched wasn't compiled with task timers enabled\n");
+#endif
+}
diff --git a/src/qsched.h b/src/qsched.h
index 47bf8e700dbd87e8b82a0453fa19c80a2092e0ab..d361525a5e768af4790abf23a50a7c937df610c6 100644
--- a/src/qsched.h
+++ b/src/qsched.h
@@ -212,6 +212,7 @@ void qsched_reset ( struct qsched *s );
 void qsched_addtask_dynamic ( struct qsched *s , int type , unsigned int flags , void *data , int data_size , int cost , qsched_res_t *locks , int nr_locks , qsched_res_t *uses , int nr_uses );
 void qsched_ensure ( struct qsched *s , int nr_tasks , int nr_res , int nr_deps , int nr_locks , int nr_uses , int size_data );
 void qsched_res_own ( struct qsched *s , qsched_res_t res , int owner );
+void qsched_dump_task_timers( struct qsched *s, char *filename );
 int qsched_get_tid();
 
 struct qsched * f_qsched_create();
diff --git a/src/task.h b/src/task.h
index c9c57d6436fe659352133ce38b79fc63c719da7e..d12229081ea84fc16a4786e425ceca8f1ff22182 100644
--- a/src/task.h
+++ b/src/task.h
@@ -57,4 +57,9 @@ struct task {
     /* Task weight for queue selection. */
     int cost, weight; 
 
+    #ifdef WITH_TASK_TIMERS
+    int tid;
+
+    #endif
+
     };