diff --git a/tools/deleteoldlogentries.py b/tools/deleteoldlogentries.py
new file mode 100644
index 000000000..1f6c60509
--- /dev/null
+++ b/tools/deleteoldlogentries.py
@@ -0,0 +1,45 @@
+import logging
+
+from datetime import timedelta, datetime
+
+from app import app
+from data.model import LogEntry
+
+logger = logging.getLogger(__name__)
+
+LOG_FORMAT = "%(asctime)s [%(process)d] [%(levelname)s] [%(name)s] %(message)s"
+BATCH_SIZE = 1000
+
+def delete_old_logentries(delete_before):
+  delete_up_to_id = (LogEntry
+    .select(LogEntry.id)
+    .where(LogEntry.datetime <= delete_before)
+    .order_by(LogEntry.id.desc())
+    .limit(1)
+    .tuples())[0][0]
+  logger.debug('Deleting up to id: %s', delete_up_to_id)
+
+  start_from_id = (LogEntry
+    .select(LogEntry.id)
+    .order_by(LogEntry.id)
+    .limit(1)
+    .tuples())[0][0]
+  logger.debug('Starting from id: %s', start_from_id)
+
+  deleted = 1
+  current_batch_end = min(start_from_id + BATCH_SIZE, delete_up_to_id)
+  while deleted > 0 or current_batch_end < delete_up_to_id:
+    deleted = (LogEntry
+      .delete()
+      .where(LogEntry.id <= current_batch_end)
+      .execute())
+    logger.debug('Deleted %s entries', deleted)
+    current_batch_end = min(current_batch_end + BATCH_SIZE, delete_up_to_id)
+
+if __name__ == '__main__':
+  logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT)
+
+  now = datetime.now()
+  one_month_ago = now - timedelta(days=30)
+
+  delete_old_logentries(one_month_ago)
\ No newline at end of file