diff --git a/tools/gerrit-success-rate.py b/tools/gerrit-success-rate.py
new file mode 100644
index 0000000000..c61133de90
--- /dev/null
+++ b/tools/gerrit-success-rate.py
@@ -0,0 +1,75 @@
+import datetime
+import json
+import requests
+
+
+today = datetime.date.today()
+thirty_days = datetime.timedelta(days=30)
+last_month = today - thirty_days
+str_today = today.strftime('%Y-%m-%d')
+str_last_month = last_month.strftime('%Y-%m-%d')
+
+
+more_changes = True
+change_count = 0
+check_successes = 0.0
+check_failures = 0.0
+gate_successes = 0.0
+gate_failures = 0.0
+while(more_changes):
+    more_changes = False
+    # We look only at merged changes to ignore Do Not Merge changes that are
+    # expected to fail intentionally.
+    r = requests.get('https://review.opendev.org/changes/?q=status:merged+'
+                     'after:{after}+before:{before}&n=100&S={offset}'.format(
+                         after=str_last_month,
+                         before=str_today,
+                         offset=(change_count + 1)))
+
+    content = r.content[4:]
+    changes = json.loads(content)
+
+    for change in changes:
+        r = requests.get('https://review.opendev.org/changes/%s/detail' % change['id'])
+        content = r.content[4:]
+        details = json.loads(content)
+        change_count += 1
+        for message in details['messages']:
+            if 'author' not in message or 'message' not in message:
+                continue
+            if message['author']['_account_id'] != 22348:
+                # Don't care about non zuul comments
+                continue
+            if '(check pipeline)' in message['message']:
+                if 'Build succeeded' in message['message']:
+                    check_successes += 1
+                elif 'Build failed' in message['message']:
+                    # explicitly check for failed builds here to avoid merge
+                    # conflict messages
+                    check_failures += 1
+            if '(gate pipeline)' in message['message']:
+                if 'Build succeeded' in message['message']:
+                    gate_successes += 1
+                elif 'Build failed' in message['message']:
+                    # explicitly check for failed builds here to avoid merge
+                    # conflict messages
+                    gate_failures += 1
+            if '_more_changes' in change:
+                more_changes = True
+
+print('Changes: %s' % change_count)
+
+print('Check Failures: %s' % check_failures)
+print('Check Successes: %s' % check_successes)
+check_total = check_failures + check_successes
+print('Check Rate of failure: %s' % (check_failures/check_total))
+
+print('Gate Failures: %s' % gate_failures)
+print('Gate Successes: %s' % gate_successes)
+gate_total = gate_failures + gate_successes
+print('Gate Rate of failure: %s' % (gate_failures/gate_total))
+
+print('Total Failures: %s' % (check_failures + gate_failures))
+print('Total Successes: %s' % (check_successes + gate_successes))
+total = check_total + gate_total
+print('Total Rate of failure: %s' % ((check_failures + gate_failures)/total))