diff --git a/noblogsmv/state.py b/noblogsmv/state.py
index 504dd6b63bf4325bc10cb1c5fd1d8442b35b4e9c..60a8ef3822b849567d472038b6254ca6fa21de2f 100644
--- a/noblogsmv/state.py
+++ b/noblogsmv/state.py
@@ -253,6 +253,23 @@ class StateMachineWorker(threading.Thread):
         return info
 
 
+class RingBuffer(object):
+
+    def __init__(self, size):
+        self.size = size
+        self.values = [None] * size
+        self.ptr = 0
+
+    def add(self, value):
+        self.values[self.ptr] = value
+        self.ptr += 1
+        if self.ptr > self.size:
+            self.ptr = 0
+
+    def get_values(self):
+        return values[self.ptr:] + values[:self.ptr]
+
+
 class StatsThread(threading.Thread):
 
     def __init__(self, sm):
@@ -285,6 +302,7 @@ class StateMachine(object):
         self.num_workers = num_workers
         self.threads = []
         self.state_count = {}
+        self.state_count_ts = {}
 
     def load_data(self, input_stream):
         with transaction(self.db) as session:
@@ -321,9 +339,22 @@ class StateMachine(object):
         with readonly_transaction(self.db) as session:
             return self.db.dump(session)
 
+    def get_current_state_count(self):
+        return self.state_count
+
+    def get_ts_state_count(self):
+        return self.state_count_ts
+
     def compute_stats(self):
         with readonly_transaction(self.db) as session:
-            self.state_count = self.db.count_by_state(session)
+            state_count = self.db.count_by_state(session)
+            state_count_ts = dict(self.state_count_ts)
+            for key, value in state_count.iteritems():
+                if key not in state_count_ts:
+                    state_count_ts[key] = RingBuffer(512)
+                state_count_ts[key].add(value)
+            self.state_count = state_count
+            self.state_count_ts = state_count_ts
 
     def run(self):
         input_queue = Queue.Queue()
diff --git a/noblogsmv/templates/index.html b/noblogsmv/templates/index.html
index 05141eac1caf8f53247dd7629f689b0ff50ad990..6616ab8b17beecd8d5b84089347b16c3e7a70f12 100644
--- a/noblogsmv/templates/index.html
+++ b/noblogsmv/templates/index.html
@@ -69,6 +69,10 @@
               {% endfor %}
             </tbody>
 	  </table>
+
+          <h4>Task states over time:</h4>
+          <img src="{{ state_count_graph }}">
+
 	</div>
 
 	<div class="tab-pane" id="tasks">
diff --git a/noblogsmv/webapp.py b/noblogsmv/webapp.py
index 6287ad9a66615f29f8243d3af703b3358ee5ea33..fe57101f4f4e7491ea6af72bce5c7e408a1a0e95 100644
--- a/noblogsmv/webapp.py
+++ b/noblogsmv/webapp.py
@@ -7,6 +7,7 @@ import time
 import urllib2
 from noblogsmv import state
 from flask import Flask, redirect, render_template, request, g
+from pygooglechart import SimpleLineChart
 
 
 app = Flask(__name__)
@@ -17,6 +18,35 @@ def before_request_handler():
     g.sm = app.config.sm
 
 
+_palette = [0xffa07a,
+            0xffdab9,
+            0x5f9ea0,
+            0xdda0dd,
+            0x6294ed,
+            0x8fbc8b,
+            0xf0e68c,
+            0xff69b4,
+            0x4ce2d3,
+            ]
+
+def _mk_stats_graph(x=450, y=270):
+    ts = g.sm.state_count_ts
+
+    chart = SimpleLineChart(x, y)
+    labels = []
+    for key, rbuf in ts.iteritems():
+        values = rbuf.get_values()
+        chart.add_data(values)
+        labels.append(key)
+    nkeys = len(labels)
+    chart.add_data([0] * nkeys)
+    chart.set_colours(_palette[:nkeys])
+    for i in xrange(nkeys - 1):
+        chart.add_fill_range(_palette[i], i, i+1)
+
+    return chart.get_url()
+
+
 @app.route('/')
 def index():
     now = time.time()
@@ -26,6 +56,7 @@ def index():
     return render_template('index.html',
                            state=cur_state,
                            state_count=state_count,
+                           state_count_graph=_mk_stats_graph(),
                            worker_info=worker_info,
                            now=time.time())
 
diff --git a/setup.py b/setup.py
index 14811eed154deb8e5945487f3e0283f7c3f0e732..fc39f7daff7c82505b5fb84eeda306c074489123 100755
--- a/setup.py
+++ b/setup.py
@@ -9,7 +9,7 @@ setup(
     author="ale",
     author_email="ale@incal.net",
     url="https://git.autistici.org/ai/noblogsmv",
-    install_requires=['Flask', 'SQLAlchemy'],
+    install_requires=['Flask', 'SQLAlchemy', 'pygooglechart'],
     setup_requires=[],
     zip_safe=True,
     packages=find_packages(),