diff --git a/client/djrandom_client/stats.py b/client/djrandom_client/stats.py
index 11eb330dc4a955e92144a90e1df7978c63ac044c..817218be96c66ae7305ca7cd0d55e25920fbef0c 100644
--- a/client/djrandom_client/stats.py
+++ b/client/djrandom_client/stats.py
@@ -25,8 +25,10 @@ class StatsDumperThread(threading.Thread):
 class Stats(object):
     """Thread-safe instrumentation."""
 
-    def __init__(self):
-        self._path = os.path.join(os.getenv('HOME'), '.djrandom.state')
+    def __init__(self, path=None):
+        if not path:
+            path = os.path.expanduser('~/.djrandom.state')
+        self._path = path
         self._data = {}
         self._lock = threading.Lock()
         if os.path.exists(self._path):
@@ -55,6 +57,3 @@ class Stats(object):
         with self._lock:
             self._data[key] = value
 
-
-# Global instance.
-data = Stats()
diff --git a/client/djrandom_client/upload.py b/client/djrandom_client/upload.py
index 7c657478f4d2fff7f17bd635e57f690fd147e724..0f42131b4c39f8d4e1c71cf5fe479faf52c8dbfb 100644
--- a/client/djrandom_client/upload.py
+++ b/client/djrandom_client/upload.py
@@ -60,12 +60,14 @@ class FileDatabase(object):
 
 class Uploader(threading.Thread):
 
-    def __init__(self, server_url, api_key, db=None):
+    def __init__(self, server_url, api_key, db_path=None,
+                 state_path=None):
         threading.Thread.__init__(self)
         self.api_key = api_key
         self.server_url = server_url
         self.queue = Queue.Queue(100)
-        self.db_path = db
+        self.db_path = db_path
+        self.stats = stats.Stats(state_path)
         self.opener = urllib2.build_opener(throttle.ThrottledHTTPHandler)
 
         user_agent = 'djrandom_client/%s (%s %s Python/%s)' % (
@@ -104,34 +106,35 @@ class Uploader(threading.Thread):
         result = self._get('/check/' + sha1)
         if result:
             log.info('%s already on server (%s)' % (path, sha1))
-            return True
+            return
         result = self._put('/upload/' + sha1, path)
         if not result:
-            raise UploadError('error uploading %s' % path)
-        stats.data.incr('uploaded_files')
+            raise UploadError('server error')
+        self.stats.incr('uploaded_files')
         log.info('successfully uploaded %s (%s)' % (path, sha1))
 
     def run(self):
         db = FileDatabase(self.db_path)
         try:
             while True:
-                stats.data.set('uploading', None)
+                self.stats.set('uploading', None)
                 path = self.queue.get()
                 if path is None:
                     break
                 if db.has(path):
                     continue
-                stats.data.set('uploading', path)
+                self.stats.set('uploading', path)
                 try:
                     self.upload(path)
                     db.add(path)
                 except Exception, e:
                     log.error('error uploading %s: %s' % (path, str(e)))
-                    stats.data.incr('errors')
-                    stats.data.set('last_error', str(e))
-                    stats.data.set('last_error_timestamp', '%i' % time.time())
+                    self.stats.incr('errors')
+                    self.stats.set('last_error', str(e))
+                    self.stats.set('last_error_timestamp', '%i' % time.time())
         finally:
             log.debug('uploader thread exiting')
+            self.stats._save()
             db.close()
 
     def stop(self):