diff --git a/warden3/warden_server/warden_server.py b/warden3/warden_server/warden_server.py
index cce4aeb13ad2f2f54fc6fc6aaee2515dc94023a7..19da3f8213f0c4e353f137088b5b60c307e05a58 100755
--- a/warden3/warden_server/warden_server.py
+++ b/warden3/warden_server/warden_server.py
@@ -727,22 +727,53 @@ class MySQL(ObjectReq):
 
     def load_maps(self):
         try:
-            self.query("DELETE FROM tags")
+            self.query("DELETE FROM tags", dml=True)
             for tag, num in self.tagmap.iteritems():
-                self.query("INSERT INTO tags(id, tag) VALUES (%s, %s)", (num, tag))
-            self.query("DELETE FROM categories")
+                self.query("INSERT INTO tags(id, tag) VALUES (%s, %s)", (num, tag), dml=True)
+            self.query("DELETE FROM categories", dml=True)
             for cat_subcat, num in self.catmap.iteritems():
                 catsplit = cat_subcat.split(".", 1)
                 category = catsplit[0]
                 subcategory = catsplit[1] if len(catsplit)>1 else None
                 self.query("INSERT INTO categories(id, category, subcategory, cat_subcat) VALUES (%s, %s, %s, %s)",
-                    (num, category, subcategory, cat_subcat))
+                    (num, category, subcategory, cat_subcat), dml=True)
             self.con.commit()
         except Exception as e:
             self.con.rollback()
             raise
 
 
+    def purge_lastlog(self, days):
+        try:
+            self.query(
+                "DELETE FROM last_events "
+                " USING last_events LEFT JOIN ("
+                "    SELECT MAX(id) AS last FROM last_events"
+                "    GROUP BY client_id"
+                " ) AS maxids ON last=id"
+                " WHERE timestamp < DATE_SUB(CURDATE(), INTERVAL %s DAY) AND last IS NULL",
+                days, dml=True)
+            affected = self.con.affected_rows()
+            self.con.commit()
+        except Exception as e:
+            self.con.rollback()
+            raise
+        return affected
+
+
+    def purge_events(self, days):
+        try:
+            self.query(
+                "DELETE FROM events WHERE received < DATE_SUB(CURDATE(), INTERVAL %s DAY)",
+                days, dml=True)
+            affected = self.con.affected_rows()
+            self.con.commit()
+        except Exception as e:
+            self.con.rollback()
+            raise
+        return affected
+
+
 
 def expose(read=1, write=0, debug=0):
 
@@ -1337,6 +1368,17 @@ def load_maps():
     server.handler.db.load_maps()
 
 
+def purge(days=30, lastlog=None, events=None):
+    if lastlog is None and events is None:
+        lastlog = events = True
+    if lastlog:
+        count = server.handler.db.purge_lastlog(days)
+        print "Purged %d lastlog entries." % count
+    if events:
+        count = server.handler.db.purge_events(days)
+        print "Purged %d events." % count
+
+
 def add_client_args(subargp, mod=False):
     subargp.add_argument("--help", action="help", help="show this help message and exit")
     if mod:
@@ -1417,6 +1459,22 @@ def get_args():
     subargp_list.add_argument("--id", action="store", type=int,
         help="client id", default=None)
 
+    subargp_purge = subargp.add_parser("purge", add_help=False,
+        description=
+            "Purge old events or lastlog records."
+            " Note that lastlog purge retains at least one newest record for each"
+            " client, even if it is more than number of 'days' old.",
+        help="purge old events or lastlog records")
+    subargp_purge.set_defaults(command=purge)
+    subargp_purge.add_argument("--help", action="help",
+        help="show this help message and exit")
+    subargp_purge.add_argument("-l", "--lastlog", action="store_true", dest="lastlog", default=None,
+        help="purge lastlog records")
+    subargp_purge.add_argument("-e", "--events", action="store_true", dest="events", default=None,
+        help="purge events")
+    subargp_purge.add_argument("-d", "--days", action="store", dest="days", type=int, default=30,
+        help="records older than 'days' back from today will get purged")
+
     subargp_loadmaps = subargp.add_parser("loadmaps", add_help=False,
         description=
             "Load 'categories' and 'tags' table from 'catmap_mysql.json' and 'tagmap_mysql.json'."