diff --git a/hypha/apply/funds/tables.py b/hypha/apply/funds/tables.py
index 3ae089117073673c9ea628347f158fdf654f9b79..4b0644e11709cad8988bdecd05513c9c14456c85 100644
--- a/hypha/apply/funds/tables.py
+++ b/hypha/apply/funds/tables.py
@@ -16,12 +16,15 @@ from wagtail.core.models import Page
 from hypha.apply.categories.models import MetaTerm
 from hypha.apply.funds.models import ApplicationSubmission, Round, ScreeningStatus
 from hypha.apply.funds.workflow import STATUSES, get_review_active_statuses
+from hypha.apply.review.models import Review
 from hypha.apply.users.groups import STAFF_GROUP_NAME
 from hypha.apply.utils.image import generate_image_tag
 from hypha.images.models import CustomImage
 
 from .widgets import Select2MultiCheckboxesWidget
 
+User = get_user_model()
+
 
 def review_filter_for_user(user):
     review_states = set(get_review_active_statuses(user))
@@ -49,7 +52,11 @@ def render_actions(table, record):
 
 
 def render_title(record):
-    return textwrap.shorten(record.title, width=30, placeholder="...")
+    try:
+        title = record.title
+    except AttributeError:
+        title = record.submission.title
+    return textwrap.shorten(title, width=30, placeholder="...")
 
 
 class SubmissionsTable(tables.Table):
@@ -171,13 +178,11 @@ def get_used_funds(request):
 
 
 def get_round_leads(request):
-    User = get_user_model()
     return User.objects.filter(submission_lead__isnull=False).distinct()
 
 
 def get_reviewers(request):
     """ All assigned reviewers, staff or admin """
-    User = get_user_model()
     return User.objects.filter(Q(submissions_reviewer__isnull=False) | Q(groups__name=STAFF_GROUP_NAME) | Q(is_superuser=True)).distinct()
 
 
@@ -359,3 +364,82 @@ class RoundsFilter(filters.FilterSet):
     lead = Select2ModelMultipleChoiceFilter(queryset=get_round_leads, label='Leads')
     active = ActiveRoundFilter(label='Active')
     round_state = OpenRoundFilter(label='Open')
+
+
+class ReviewerLeaderboardFilterForm(forms.ModelForm):
+    """
+    Form to "clean" a list of User objects to their PKs.
+
+    The Reviewer Leaderboard table is a list of User objects, however we also want
+    the ability to filter down to N Users (reviewers).  Django filter is converting
+    the selected PKs to User objects, however we can't filter a User QuerySet
+    with User objects.  So this form converts back to a list of User PKs using
+    the clean_reviewer method.
+    """
+    class Meta:
+        fields = ["id"]
+        model = User
+
+    def clean_reviewer(self):
+        return [u.id for u in self.cleaned_data['reviewer']]
+
+
+class ReviewerLeaderboardFilter(filters.FilterSet):
+    query = filters.CharFilter(field_name='full_name', lookup_expr="icontains", widget=forms.HiddenInput)
+
+    reviewer = Select2ModelMultipleChoiceFilter(
+        field_name='pk',
+        label='Reviewers',
+        queryset=get_reviewers,
+    )
+    funds = Select2ModelMultipleChoiceFilter(
+        field_name='submission__page',
+        label='Funds',
+        queryset=get_used_funds,
+    )
+    rounds = Select2ModelMultipleChoiceFilter(
+        field_name='submission__round',
+        label='Rounds',
+        queryset=get_used_rounds,
+    )
+
+    class Meta:
+        fields = [
+            'reviewer',
+            'funds',
+            'rounds',
+        ]
+        form = ReviewerLeaderboardFilterForm
+        model = User
+
+
+class ReviewerLeaderboardTable(tables.Table):
+    full_name = tables.LinkColumn('funds:submissions:reviewer_leaderboard_detail', args=[A('pk')], orderable=True, verbose_name="Reviewer", attrs={'td': {'class': 'title'}})
+
+    class Meta:
+        model = User
+        fields = [
+            'full_name',
+            'total',
+            'ninety_days',
+            'this_year',
+            'last_year',
+        ]
+        order_by = ('-total',)
+        attrs = {'class': 'all-reviews-table'}
+        empty_text = _('No reviews available')
+
+
+class ReviewerLeaderboardDetailTable(tables.Table):
+    title = tables.LinkColumn('funds:submissions:reviews:review', text=render_title, args=[A('submission_id'), A('pk')], orderable=True, verbose_name="Submission", attrs={'td': {'data-title-tooltip': lambda record: record.submission.title, 'class': 'title js-title'}})
+
+    class Meta:
+        model = Review
+        fields = [
+            'title',
+            'recommendation',
+            'created_at',
+        ]
+        order_by = ('-created_at',)
+        attrs = {'class': 'all-reviews-table'}
+        empty_text = _('No reviews available')
diff --git a/hypha/apply/funds/templates/funds/reviewer_leaderboard.html b/hypha/apply/funds/templates/funds/reviewer_leaderboard.html
new file mode 100644
index 0000000000000000000000000000000000000000..a4b345da1d8651a0b31ffddb6234defeda1061a9
--- /dev/null
+++ b/hypha/apply/funds/templates/funds/reviewer_leaderboard.html
@@ -0,0 +1,29 @@
+{% extends "funds/submissions_overview.html" %}
+{% load static %}
+{% load render_table from django_tables2 %}
+
+{% block title %}Reviews{% endblock %}
+
+{% block content %}
+<div class="admin-bar">
+    <div class="admin-bar__inner wrapper--search">
+        {% block page_header %}
+            <div>
+                <h1 class="gamma heading heading--no-margin heading--bold">Reviewer Leaderboard</h1>
+                <h5>Track and explore the reviews</h5>
+            </div>
+        {% endblock %}
+        {% block page_header_tabs %}
+            {{ block.super }}
+        {% endblock %}
+    </div>
+</div>
+
+<div class="wrapper wrapper--large wrapper--inner-space-medium">
+    {% block table %}
+        {% include "funds/includes/table_filter_and_search.html" with filter_form=filter_form search_term=search_term search_placeholder="reviewers" use_search=True filter_action=filter_action use_batch_actions=False heading="All reviewers" %}
+
+        {% render_table table %}
+    {% endblock %}
+</div>
+{% endblock %}
diff --git a/hypha/apply/funds/templates/funds/reviewer_leaderboard_detail.html b/hypha/apply/funds/templates/funds/reviewer_leaderboard_detail.html
new file mode 100644
index 0000000000000000000000000000000000000000..2c063c3761eac442f2edef32997a488aecd12197
--- /dev/null
+++ b/hypha/apply/funds/templates/funds/reviewer_leaderboard_detail.html
@@ -0,0 +1,27 @@
+{% extends "funds/submissions_overview.html" %}
+{% load static %}
+{% load render_table from django_tables2 %}
+
+{% block title %}Reviews{% endblock %}
+
+{% block content %}
+<div class="admin-bar">
+    <div class="admin-bar__inner wrapper--search">
+        {% block page_header %}
+            <div>
+                <h1 class="gamma heading heading--no-margin heading--bold">Reviews by {{ object }}</h1>
+                <h5>Track and explore the reviews</h5>
+            </div>
+        {% endblock %}
+        {% block page_header_tabs %}
+            {{ block.super }}
+        {% endblock %}
+    </div>
+</div>
+
+<div class="wrapper wrapper--large wrapper--inner-space-medium">
+    {% block table %}
+        {% render_table table %}
+    {% endblock %}
+</div>
+{% endblock %}
diff --git a/hypha/apply/funds/templates/funds/submissions_overview.html b/hypha/apply/funds/templates/funds/submissions_overview.html
index b83f169b8d51f75cb78d742ef53ffb4157eed90b..ed04c2dc743df2fd3db0de08f02a48e02fc19393 100644
--- a/hypha/apply/funds/templates/funds/submissions_overview.html
+++ b/hypha/apply/funds/templates/funds/submissions_overview.html
@@ -10,9 +10,14 @@
                 <h1 class="gamma heading heading--no-margin heading--bold">Submissions</h1>
                 <h5>Track and explore recent submissions</h5>
             </div>
+        {% endblock %}
+        {% block page_header_tabs %}
             {% if request.user.is_apply_staff %}
             <div class="tabs">
                 <div class="tabs__container">
+                    <a class="tab__item tab__item--right" href="{% url 'apply:submissions:reviewer_leaderboard' %}">
+                        Reviews
+                    </a>
                     <a class="tab__item tab__item--right" href="{% url 'apply:submissions:result' %}">
                         Results
                     </a>
diff --git a/hypha/apply/funds/templates/funds/submissions_result.html b/hypha/apply/funds/templates/funds/submissions_result.html
index 6510c3a8d294e3b2bced8e5ea18d0ed1a2ea472f..8b5afd483b1f64bf45ed2335791a9fc99707fc7c 100644
--- a/hypha/apply/funds/templates/funds/submissions_result.html
+++ b/hypha/apply/funds/templates/funds/submissions_result.html
@@ -1,19 +1,19 @@
-{% extends "base-apply.html" %}
+{% extends "funds/submissions_overview.html" %}
 {% load static %}
 {% block title %}Submissions results{% endblock %}
 
-{% block extra_css %}
-{{ filter.form.media.css }}
-{% endblock %}
-
 {% block content %}
 <div class="admin-bar">
     <div class="admin-bar__inner wrapper--search">
         {% block page_header %}
             <div>
                 <h1 class="gamma heading heading--no-margin heading--bold">Submissions results</h1>
+                <h5>Track and explore the results</h5>
             </div>
         {% endblock %}
+        {% block page_header_tabs %}
+            {{ block.super }}
+        {% endblock %}
     </div>
 </div>
 
@@ -27,9 +27,3 @@
     </div>
 </div>
 {% endblock %}
-
-{% block extra_js %}
-    {{ filter.form.media.js }}
-    <script src="https://cdnjs.cloudflare.com/ajax/libs/url-search-params/1.1.0/url-search-params.js"></script>
-    <script src="{% static 'js/apply/submission-filters.js' %}"></script>
-{% endblock %}
diff --git a/hypha/apply/funds/tests/test_views.py b/hypha/apply/funds/tests/test_views.py
index 36213ca12ad78a1d106a508771f3c12f84eda103..46ad7bd97eef0f514cee1a31f1470bd8999a62b7 100644
--- a/hypha/apply/funds/tests/test_views.py
+++ b/hypha/apply/funds/tests/test_views.py
@@ -5,7 +5,7 @@ from bs4 import BeautifulSoup
 from django.contrib.auth.models import AnonymousUser
 from django.core.exceptions import PermissionDenied
 from django.http import Http404
-from django.test import RequestFactory, TestCase
+from django.test import RequestFactory, TestCase, override_settings
 from django.urls import reverse
 from django.utils import timezone
 from django.utils.text import slugify
@@ -30,6 +30,8 @@ from hypha.apply.projects.tests.factories import ProjectFactory
 from hypha.apply.review.tests.factories import ReviewFactory
 from hypha.apply.users.tests.factories import (
     ApplicantFactory,
+    CommunityReviewerFactory,
+    PartnerFactory,
     ReviewerFactory,
     StaffFactory,
     SuperUserFactory,
@@ -1214,3 +1216,31 @@ class TestUserReminderDeleteView(BaseProjectDeleteTestCase):
         reminder = ReminderFactory()
         response = self.get_page(reminder)
         self.assertEqual(response.status_code, 403)
+
+
+@override_settings(ROOT_URLCONF='hypha.apply.urls')
+class TestReviewerLeaderboard(TestCase):
+    def test_applicant_cannot_access_reviewer_leaderboard(self):
+        self.client.force_login(ApplicantFactory())
+        response = self.client.get('/apply/submissions/reviews/', follow=True, secure=True)
+        self.assertEqual(response.status_code, 403)
+
+    def test_community_reviewer_cannot_access_reviewer_leaderboard(self):
+        self.client.force_login(CommunityReviewerFactory())
+        response = self.client.get('/apply/submissions/reviews/', follow=True, secure=True)
+        self.assertEqual(response.status_code, 403)
+
+    def test_partner_cannot_access_reviewer_leaderboard(self):
+        self.client.force_login(PartnerFactory())
+        response = self.client.get('/apply/submissions/reviews/', follow=True, secure=True)
+        self.assertEqual(response.status_code, 403)
+
+    def test_reviewer_cannot_access_leader_board(self):
+        self.client.force_login(ReviewerFactory())
+        response = self.client.get('/apply/submissions/reviews/', follow=True, secure=True)
+        self.assertEqual(response.status_code, 403)
+
+    def test_staff_can_access_leaderboard(self):
+        self.client.force_login(StaffFactory())
+        response = self.client.get('/apply/submissions/reviews/', follow=True, secure=True)
+        self.assertEqual(response.status_code, 200)
diff --git a/hypha/apply/funds/urls.py b/hypha/apply/funds/urls.py
index fc8321ededdefe1c62fde713eb714f114e5d3826..d63cbdf5b699e81ced2c6cb1813754a184497c09 100644
--- a/hypha/apply/funds/urls.py
+++ b/hypha/apply/funds/urls.py
@@ -4,6 +4,8 @@ from hypha.apply.projects import urls as projects_urls
 
 from .views import (
     ReminderDeleteView,
+    ReviewerLeaderboard,
+    ReviewerLeaderboardDetail,
     RevisionCompareView,
     RevisionListView,
     RoundListView,
@@ -43,6 +45,10 @@ submission_urls = ([
         path('', SubmissionUserFlaggedView.as_view(), name="flagged"),
         path('staff/', SubmissionStaffFlaggedView.as_view(), name="staff_flagged"),
     ])),
+    path('reviews/', include([
+        path('', ReviewerLeaderboard.as_view(), name="reviewer_leaderboard"),
+        path('<int:pk>/', ReviewerLeaderboardDetail.as_view(), name="reviewer_leaderboard_detail"),
+    ])),
     path('<int:pk>/', include([
         path('', SubmissionDetailView.as_view(), name="detail"),
         path('edit/', SubmissionEditView.as_view(), name="edit"),
diff --git a/hypha/apply/funds/views.py b/hypha/apply/funds/views.py
index 5c45c7178bbd4208a94df2bc55e123b5186f6afa..c8af701c23e6da546f50938f5a399b6c4ae93e97 100644
--- a/hypha/apply/funds/views.py
+++ b/hypha/apply/funds/views.py
@@ -1,7 +1,9 @@
 from copy import copy
+from datetime import timedelta
 from statistics import mean
 
 from django.contrib import messages
+from django.contrib.auth import get_user_model
 from django.contrib.auth.decorators import login_required, permission_required
 from django.contrib.auth.mixins import UserPassesTestMixin
 from django.contrib.humanize.templatetags.humanize import intcomma
@@ -10,6 +12,7 @@ from django.db.models import Count, F, Q
 from django.http import FileResponse, Http404, HttpResponseRedirect
 from django.shortcuts import get_object_or_404
 from django.urls import reverse_lazy
+from django.utils import timezone
 from django.utils.decorators import method_decorator
 from django.utils.safestring import mark_safe
 from django.utils.translation import ugettext_lazy as _
@@ -41,6 +44,7 @@ from hypha.apply.determinations.views import (
 )
 from hypha.apply.projects.forms import CreateProjectForm
 from hypha.apply.projects.models import Project
+from hypha.apply.review.models import Review
 from hypha.apply.review.views import ReviewContextMixin
 from hypha.apply.users.decorators import staff_required
 from hypha.apply.utils.pdfs import draw_submission_content, make_pdf
@@ -76,6 +80,9 @@ from .models import (
 from .permissions import is_user_has_access_to_view_submission
 from .tables import (
     AdminSubmissionsTable,
+    ReviewerLeaderboardDetailTable,
+    ReviewerLeaderboardFilter,
+    ReviewerLeaderboardTable,
     ReviewerSubmissionsTable,
     RoundsFilter,
     RoundsTable,
@@ -1179,3 +1186,53 @@ class SubmissionResultView(FilterView):
             average = round(mean(values))
 
         return {'total': total, 'average': average}
+
+
+@method_decorator(staff_required, name='dispatch')
+class ReviewerLeaderboard(SingleTableMixin, FilterView):
+    filterset_class = ReviewerLeaderboardFilter
+    filter_action = ''
+    table_class = ReviewerLeaderboardTable
+    table_pagination = False
+    template_name = 'funds/reviewer_leaderboard.html'
+
+    def get_context_data(self, **kwargs):
+        search_term = self.request.GET.get('query')
+
+        return super().get_context_data(
+            search_term=search_term,
+            filter_action=self.filter_action,
+            **kwargs,
+        )
+
+    def get_queryset(self):
+        # Only list reviewers.
+        return self.filterset_class._meta.model.objects.reviewers()
+
+    def get_table_data(self):
+        ninety_days_ago = timezone.now() - timedelta(days=90)
+        this_year = timezone.now().year
+        last_year = timezone.now().year - 1
+        return super().get_table_data().annotate(
+            total=Count('assignedreviewers__review'),
+            ninety_days=Count('assignedreviewers__review', filter=Q(assignedreviewers__review__created_at__date__gte=ninety_days_ago)),
+            this_year=Count('assignedreviewers__review', filter=Q(assignedreviewers__review__created_at__year=this_year)),
+            last_year=Count('assignedreviewers__review', filter=Q(assignedreviewers__review__created_at__year=last_year)),
+        )
+
+
+@method_decorator(staff_required, name='dispatch')
+class ReviewerLeaderboardDetail(SingleTableMixin, ListView):
+    model = Review
+    table_class = ReviewerLeaderboardDetailTable
+    paginator_class = LazyPaginator
+    table_pagination = {'per_page': 25}
+    template_name = 'funds/reviewer_leaderboard_detail.html'
+
+    def get_context_data(self, **kwargs):
+        User = get_user_model()
+        obj = User.objects.get(pk=self.kwargs.get('pk'))
+        return super().get_context_data(object=obj, **kwargs)
+
+    def get_table_data(self):
+        return super().get_table_data().filter(author__reviewer_id=self.kwargs.get('pk')).select_related('submission')
diff --git a/hypha/apply/review/models.py b/hypha/apply/review/models.py
index 0f91ec9def67aa6df9c0c0a339c9218fa5f455f3..6d782e85512b25adf15897b88c8bb6d987992066 100644
--- a/hypha/apply/review/models.py
+++ b/hypha/apply/review/models.py
@@ -101,6 +101,9 @@ class ReviewQuerySet(models.QuerySet):
     def by_partners(self):
         return self.submitted()._by_group(PARTNER_GROUP_NAME)
 
+    def by_user(self, user):
+        return self.submitted().filter(author__reviewer=user).order_by('-created_at')
+
     def staff_score(self):
         return self.by_staff().score()
 
diff --git a/hypha/apply/users/tests/factories.py b/hypha/apply/users/tests/factories.py
index f9b4b231293629c2be50c9c0d2b26d26f66d656e..59fb930943b0aefa62d578d68fd6782e9f2e748b 100644
--- a/hypha/apply/users/tests/factories.py
+++ b/hypha/apply/users/tests/factories.py
@@ -8,6 +8,8 @@ from django.utils.text import slugify
 from ..groups import (
     APPLICANT_GROUP_NAME,
     APPROVER_GROUP_NAME,
+    COMMUNITY_REVIEWER_GROUP_NAME,
+    PARTNER_GROUP_NAME,
     REVIEWER_GROUP_NAME,
     STAFF_GROUP_NAME,
 )
@@ -90,3 +92,17 @@ class ApplicantFactory(UserFactory):
     def groups(self, create, extracted, **kwargs):
         if create:
             self.groups.add(GroupFactory(name=APPLICANT_GROUP_NAME))
+
+
+class CommunityReviewerFactory(UserFactory):
+    @factory.post_generation
+    def groups(self, create, extracted, **kwargs):
+        if create:
+            self.groups.add(GroupFactory(name=COMMUNITY_REVIEWER_GROUP_NAME))
+
+
+class PartnerFactory(UserFactory):
+    @factory.post_generation
+    def groups(self, create, extracted, **kwargs):
+        if create:
+            self.groups.add(GroupFactory(name=PARTNER_GROUP_NAME))
diff --git a/hypha/static_src/src/sass/apply/abstracts/_mixins.scss b/hypha/static_src/src/sass/apply/abstracts/_mixins.scss
index ec269cd16c687695bcba7835739154ed2a8aae54..d8069921a066642723a2af2e30148271525553a7 100644
--- a/hypha/static_src/src/sass/apply/abstracts/_mixins.scss
+++ b/hypha/static_src/src/sass/apply/abstracts/_mixins.scss
@@ -196,7 +196,7 @@
 
                 &::after {
                     position: absolute;
-                    top: 32px;
+                    top: 50%;
                     margin-left: 3px;
                 }
 
diff --git a/hypha/static_src/src/sass/apply/components/_all-reviews-table.scss b/hypha/static_src/src/sass/apply/components/_all-reviews-table.scss
new file mode 100644
index 0000000000000000000000000000000000000000..bf46e5a2167580bd23847268f3a8ab110f508333
--- /dev/null
+++ b/hypha/static_src/src/sass/apply/components/_all-reviews-table.scss
@@ -0,0 +1,72 @@
+.all-reviews-table {
+    @include table-ordering-styles;
+    $root: &;
+    font-size: 14px;
+
+
+    thead {
+        display: none;
+
+        @include media-query($table-breakpoint) {
+            display: table-header-group;
+        }
+
+        tr {
+            &:hover {
+                box-shadow: none;
+            }
+        }
+    }
+
+    tbody {
+        td {
+            &.title {
+                position: relative;
+                padding-top: 15px;
+                padding-left: 10px;
+                font-weight: $weight--bold;
+
+                @include media-query($table-breakpoint) {
+                    display: flex;
+                    align-items: center;
+                }
+
+                @include media-query(desktop) {
+                    display: table-cell;
+                }
+
+                &.has-tooltip {
+                    @include media-query($table-breakpoint) {
+                        &::before {
+                            position: absolute;
+                            top: 50px;
+                            left: 45px;
+                            z-index: -1;
+                            width: 200px;
+                            padding: 5px;
+                            font-size: 12px;
+                            font-weight: $weight--normal;
+                            white-space: normal;
+                            background: $color--sky-blue;
+                            border: 1px solid $color--marine;
+                            content: attr(data-title-tooltip);
+                            opacity: 0;
+                            transition: opacity $transition;
+                        }
+
+                        &:hover {
+                            &::before {
+                                z-index: 10;
+                                opacity: 1;
+                            }
+                        }
+                    }
+                }
+
+                a {
+                    color: $color--primary;
+                }
+            }
+        }
+    }
+}
diff --git a/hypha/static_src/src/sass/apply/main.scss b/hypha/static_src/src/sass/apply/main.scss
index 4c68827bf29f9e444a594f9417c9a10d71697735..2ac36be09675a5081891c818447450973a9d1d63 100644
--- a/hypha/static_src/src/sass/apply/main.scss
+++ b/hypha/static_src/src/sass/apply/main.scss
@@ -10,6 +10,7 @@
 // Components
 @import 'components/alert';
 @import 'components/all-submissions-table';
+@import 'components/all-reviews-table';
 @import 'components/admin-bar';
 @import 'components/actions-bar';
 @import 'components/card';