diff --git a/tcms/rpc/api/testcase.py b/tcms/rpc/api/testcase.py
index 1334a3285f..487ef5b255 100644
--- a/tcms/rpc/api/testcase.py
+++ b/tcms/rpc/api/testcase.py
@@ -5,6 +5,7 @@
 from django.db.models.functions import Coalesce
 from django.forms import EmailField, ValidationError
 from django.forms.models import model_to_dict
+from django.utils.dateparse import parse_duration
 from modernrpc.core import REQUEST_KEY, rpc_method
 
 from tcms.core import helpers
@@ -279,9 +280,19 @@ def filter(query=None):  # pylint: disable=redefined-builtin
         :return: Serialized list of :class:`tcms.testcases.models.TestCase` objects.
         :rtype: list(dict)
     """
+
     if query is None:
         query = {}
 
+    if "setup_duration" in query:
+        query["setup_duration"] = parse_duration(query["setup_duration"])
+
+    if "testing_duration" in query:
+        query["testing_duration"] = parse_duration(query["testing_duration"])
+
+    if "expected_duration" in query:
+        query["expected_duration"] = parse_duration(query["expected_duration"])
+
     qs = (
         TestCase.objects.annotate(
             expected_duration=Coalesce("setup_duration", timedelta(0))
diff --git a/tcms/rpc/tests/test_testcase.py b/tcms/rpc/tests/test_testcase.py
index ca2e00a37d..3a18f17430 100644
--- a/tcms/rpc/tests/test_testcase.py
+++ b/tcms/rpc/tests/test_testcase.py
@@ -223,6 +223,35 @@ def test_duration_properties_in_result(
         self.assertEqual(result[0]["testing_duration"], testing_duration)
         self.assertEqual(result[0]["expected_duration"], expected_duration)
 
+    def test_filter_by_setup_duration(self):
+        case = TestCaseFactory(setup_duration=timedelta(seconds=45))
+
+        result = self.rpc_client.TestCase.filter({"setup_duration": "0:00:45"})
+
+        self.assertIsNotNone(result)
+        self.assertEqual(len(result), 1)
+        self.assertEqual(result[0]["id"], case.pk)
+
+    def test_filter_by_testing_duration(self):
+        case = TestCaseFactory(testing_duration=timedelta(minutes=2))
+
+        result = self.rpc_client.TestCase.filter({"testing_duration": "0:02:00"})
+
+        self.assertIsNotNone(result)
+        self.assertEqual(len(result), 1)
+        self.assertEqual(result[0]["id"], case.pk)
+
+    def test_filter_by_expected_duration(self):
+        case = TestCaseFactory(
+            setup_duration=timedelta(seconds=45), testing_duration=timedelta(minutes=2)
+        )
+
+        result = self.rpc_client.TestCase.filter({"expected_duration": "0:02:45"})
+
+        self.assertIsNotNone(result)
+        self.assertEqual(len(result), 1)
+        self.assertEqual(result[0]["id"], case.pk)
+
 
 class TestUpdate(APITestCase):
     non_existing_username = "FakeUsername"
diff --git a/tcms/testcases/forms.py b/tcms/testcases/forms.py
index d3857f963e..5af2b68ae9 100644
--- a/tcms/testcases/forms.py
+++ b/tcms/testcases/forms.py
@@ -124,6 +124,18 @@ class Meta:
         widget=forms.CheckboxSelectMultiple(),
         required=False,
     )
+    setup_duration = forms.DurationField(
+        widget=DurationWidget(),
+        required=False,
+    )
+    testing_duration = forms.DurationField(
+        widget=DurationWidget(),
+        required=False,
+    )
+    expected_duration = forms.DurationField(
+        widget=DurationWidget(),
+        required=False,
+    )
 
     def populate(self, product_id=None):
         if product_id:
diff --git a/tcms/testcases/static/testcases/js/search.js b/tcms/testcases/static/testcases/js/search.js
index 758f0da3b5..a1d195d845 100644
--- a/tcms/testcases/static/testcases/js/search.js
+++ b/tcms/testcases/static/testcases/js/search.js
@@ -52,6 +52,23 @@ function pre_process_data (data, callback) {
   })
 }
 
+function formatDuration (seconds) {
+  const numSecondsInDay = 24 * 60 * 60
+  const days = Math.floor(seconds / numSecondsInDay)
+  const rest = seconds % numSecondsInDay
+
+  const date = new Date(0)
+  date.setSeconds(rest)
+  const timeString = date.toISOString().substr(11, 8)
+
+  if (days === 0) {
+    return timeString
+  }
+
+  const dayOrDays = days === 1 ? 'day' : 'days'
+  return `${days} ${dayOrDays}, ${timeString}`
+}
+
 $(document).ready(function () {
   const table = $('#resultsTable').DataTable({
     pageLength: $('#navbar').data('defaultpagesize'),
@@ -106,6 +123,18 @@ $(document).ready(function () {
         params.is_automated = false
       };
 
+      if ($('#id_setup_duration').val() !== '0') {
+        params.setup_duration = $('#id_setup_duration').val()
+      };
+
+      if (($('#id_testing_duration').val() !== '0')) {
+        params.testing_duration = $('#id_testing_duration').val()
+      };
+
+      if (($('#id_expected_duration').val() !== '0')) {
+        params.expected_duration = $('#id_expected_duration').val()
+      };
+
       const text = $('#id_text').val()
       if (text) {
         params.text__icontains = text
@@ -145,7 +174,25 @@ $(document).ready(function () {
       { data: 'case_status__name' },
       { data: 'is_automated' },
       { data: 'author__username' },
-      { data: 'tag_names' }
+      { data: 'tag_names' },
+      {
+        data: 'setup_duration',
+        render: function (data, type, full, meta) {
+          return formatDuration(data)
+        }
+      },
+      {
+        data: 'testing_duration',
+        render: function (data, type, full, meta) {
+          return formatDuration(data)
+        }
+      },
+      {
+        data: 'expected_duration',
+        render: function (data, type, full, meta) {
+          return formatDuration(data)
+        }
+      }
     ],
     dom: 't',
     language: {
diff --git a/tcms/testcases/templates/testcases/search.html b/tcms/testcases/templates/testcases/search.html
index 05d7311fc4..0301a3274e 100644
--- a/tcms/testcases/templates/testcases/search.html
+++ b/tcms/testcases/templates/testcases/search.html
@@ -2,6 +2,10 @@
 {% load i18n %}
 {% load static %}
 
+{% block head %}
+    {{ form.media }}
+{% endblock %}
+
 {% block title %}{% trans "Search test cases" %}{% endblock %}
 
 {% block contents %}
@@ -128,6 +132,29 @@
 
         </div>
 
+        <div class="form-group">
+            <label class="col-md-1 col-lg-1">{% trans "Setup duration" %}</label>
+            <div class="col-md-3 col-lg-3">
+                <div id="setup_duration">
+                    {{ form.setup_duration }}
+                </div>
+            </div>
+
+            <label class="col-md-1 col-lg-1">{% trans "Testing duration" %}</label>
+            <div class="col-md-3 col-lg-3">
+                <div id="testing-duration">
+                    {{ form.testing_duration }}
+                </div>
+            </div>
+
+            <label class="col-md-1 col-lg-1">{% trans "Expected duration" %}</label>
+            <div class="col-md-3 col-lg-3">
+                <div id="expected-duration">
+                    {{ form.expected_duration }}
+                </div>
+            </div>
+        </div>
+
         <div class="form-group">
             <div class="col-md-1 col-lg-1">
                 <button id="btn_search" type="submit" class="btn btn-default btn-lg">{% trans "Search" %}</button>
@@ -151,6 +178,9 @@
                     <th>{% trans "Automated" %}</th>
                     <th>{% trans "Author" %}</th>
                     <th>{% trans "Tags" %}</th>
+                    <th>{% trans "Setup duration" %}</th>
+                    <th>{% trans "Testing duration" %}</th>
+                    <th>{% trans "Expected duration" %}</th>
                 </tr>
             </thead>
         </table>