diff --git a/.gitlab-ci.yaml b/.gitlab-ci.yaml
index 3184bf82418b97b2a98082787df277f5f11648a8..6fdeae2ab2642d1513debf3dae0d7db91292798a 100644
--- a/.gitlab-ci.yaml
+++ b/.gitlab-ci.yaml
@@ -7,6 +7,7 @@ stages:
 - data-supply
 - deploy
 - e2e-test
+- benchmark-tests
 - post-deploy
 
 variables:
@@ -274,3 +275,133 @@ tags_api_smoketest_negative:
     reports:
       junit: api_smoketest_tags_api_negative.xml
 
+.benchmark_tests: &common_api_benchmarks
+  stage: benchmark-tests
+  environment: hive-4.pl.syncad.com
+  needs:
+    - job: hivemind_start_server
+      artifacts: true
+
+  variables:
+    GIT_STRATEGY: none
+
+  rules:
+    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
+      when: always
+    - if: '$CI_PIPELINE_SOURCE == "push"'
+      when: manual
+    - when: on_success
+
+  tags:
+      - hivemind
+
+bridge_api_smoketest_benchmark:
+  <<: *common_api_benchmarks
+
+  script:
+    - scripts/ci_start_api_benchmark.sh localhost $HIVEMIND_HTTP_PORT tests/tests_api/hivemind/tavern/bridge_api_patterns/ api_benchmark_bridge
+
+  artifacts:
+    when: always
+    paths:
+      - tavern_benchmark_report_api_benchmark_bridge.html
+
+bridge_api_smoketest_negative_benchmark:
+  <<: *common_api_benchmarks
+
+  script:
+    - scripts/ci_start_api_benchmark.sh localhost $HIVEMIND_HTTP_PORT tests/tests_api/hivemind/tavern/bridge_api_negative/ api_benchmark_bridge_negative
+
+  artifacts:
+    when: always
+    paths:
+      - tavern_benchmark_report_api_benchmark_bridge_negative.html
+
+condenser_api_smoketest_benchmark:
+  <<: *common_api_benchmarks
+
+  script:
+    - scripts/ci_start_api_benchmark.sh localhost $HIVEMIND_HTTP_PORT tests/tests_api/hivemind/tavern/condenser_api_patterns/ api_benchmark_condenser
+
+  artifacts:
+    when: always
+    paths:
+      - tavern_benchmark_report_api_benchmark_condenser.html
+
+condenser_api_smoketest_negative_benchmark:
+  <<: *common_api_benchmarks
+
+  script:
+    - scripts/ci_start_api_benchmark.sh localhost $HIVEMIND_HTTP_PORT tests/tests_api/hivemind/tavern/condenser_api_negative/ api_benchmark_condenser_negative
+
+  artifacts:
+    when: always
+    paths:
+      - tavern_benchmark_report_api_benchmark_condenser_negative.html
+
+database_api_smoketest_benchmark:
+  <<: *common_api_benchmarks
+
+  script:
+    - scripts/ci_start_api_benchmark.sh localhost $HIVEMIND_HTTP_PORT tests/tests_api/hivemind/tavern/database_api_patterns/ api_benchmark_database
+
+  artifacts:
+    when: always
+    paths:
+      - tavern_benchmark_report_api_benchmark_database.html
+
+database_api_smoketest_negative_benchmark:
+  <<: *common_api_benchmarks
+
+  script:
+    - scripts/ci_start_api_benchmark.sh localhost $HIVEMIND_HTTP_PORT tests/tests_api/hivemind/tavern/database_api_negative/ api_benchmark_database_negative
+
+  artifacts:
+    when: always
+    paths:
+      - tavern_benchmark_report_api_benchmark_database_negative.html
+
+follow_api_smoketest_benchmark:
+  <<: *common_api_benchmarks
+
+  script:
+    - scripts/ci_start_api_benchmark.sh localhost $HIVEMIND_HTTP_PORT tests/tests_api/hivemind/tavern/follow_api_patterns/ api_benchmark_follow
+
+  artifacts:
+    when: always
+    paths:
+      - tavern_benchmark_report_api_benchmark_follow.html
+
+follow_api_smoketest_negative_benchmark:
+  <<: *common_api_benchmarks
+
+  script:
+    - scripts/ci_start_api_benchmark.sh localhost $HIVEMIND_HTTP_PORT tests/tests_api/hivemind/tavern/follow_api_negative/ api_benchmark_follow_negative
+
+  artifacts:
+    when: always
+    paths:
+      - tavern_benchmark_report_api_benchmark_follow_negative.html
+
+tags_api_smoketest_benchmark:
+  <<: *common_api_benchmarks
+
+  script:
+    - scripts/ci_start_api_benchmark.sh localhost $HIVEMIND_HTTP_PORT tests/tests_api/hivemind/tavern/tags_api_patterns/ api_benchmark_tags
+
+  artifacts:
+    when: always
+    paths:
+      - tavern_benchmark_report_api_benchmark_tags.html
+
+tags_api_smoketest_negative_benchmark:
+  <<: *common_api_benchmarks
+
+  script:
+    - scripts/ci_start_api_benchmark.sh localhost $HIVEMIND_HTTP_PORT tests/tests_api/hivemind/tavern/tags_api_negative/ api_benchmark_tags_negative
+
+  artifacts:
+    when: always
+    paths:
+      - tavern_benchmark_report_api_benchmark_tags_negative.html
+
diff --git a/scripts/ci_start_api_benchmark.sh b/scripts/ci_start_api_benchmark.sh
new file mode 100755
index 0000000000000000000000000000000000000000..4be4617875a17e1b545b7ba317b57923162fca17
--- /dev/null
+++ b/scripts/ci_start_api_benchmark.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# $1 - server address
+# $2 - server port
+# $3 - path to test directory
+# $4 - name of the benchmark script file
+
+set -e
+
+echo "=========================  BENCHMARKS  ================================="
+echo "Server address: $1"
+echo "Server port: $2"
+echo "Test directory to be processed: $3"
+echo "Benchmark test file name: $4.py"
+
+BASE_DIR=$(pwd)
+echo "Script base dir is: $BASE_DIR"
+
+pip3 install tox --user
+
+echo "Creating benchmark test file as: $4.py"
+$BASE_DIR/tests/tests_api/hivemind/benchmarks/benchmark_generator.py $3 "$4.py" "http://$1:$2"
+echo "Running benchmark tests on http://$1:$2"
+tox -e benchmark -- --benchmark-json="$4.json" "$4.py"
+echo "Creating html report from $4.json"
+$BASE_DIR/scripts/json_report_parser.py $3 "$4.json"
\ No newline at end of file
diff --git a/scripts/ci_start_api_smoketest.sh b/scripts/ci_start_api_smoketest.sh
index b85befd491532352b95bf4c7c45742bf804e2de7..17ff0f06f1d677b7b0cbf16cc58b97c9424d1d33 100755
--- a/scripts/ci_start_api_smoketest.sh
+++ b/scripts/ci_start_api_smoketest.sh
@@ -9,4 +9,4 @@ echo Attempting to start tests on hivemind instance listeing on: $HIVEMIND_ADDRE
 
 echo "Selected test group (if empty all will be executed): $3"
 
-tox -- -W ignore::pytest.PytestDeprecationWarning -n auto --durations=0 --junitxml=../../../../$4 $3
+tox -e tavern -- -W ignore::pytest.PytestDeprecationWarning -n auto --durations=0 --junitxml=../../../../$4 $3
diff --git a/scripts/json_report_parser.py b/scripts/json_report_parser.py
new file mode 100755
index 0000000000000000000000000000000000000000..4a553dee6dfea5ccd0d2b0186b1adf6df733a077
--- /dev/null
+++ b/scripts/json_report_parser.py
@@ -0,0 +1,83 @@
+#!/usr/bin/python3
+
+import xml.dom.minidom
+import os
+from sys import exit
+from json import dumps, load
+
+def get_request_from_yaml(path_to_yaml):
+    import yaml
+    yaml_document = None
+    with open(path_to_yaml, "r") as yaml_file:
+        yaml_document = yaml.load(yaml_file, Loader=yaml.BaseLoader)
+    if "stages" in yaml_document:
+        if "request" in yaml_document["stages"][0]:
+            json_parameters = yaml_document["stages"][0]["request"].get("json", None)
+            assert json_parameters is not None, "Unable to find json parameters in request"
+            return dumps(json_parameters)
+    return ""
+
+def make_class_path_dict(root_dir):
+    import os
+    from fnmatch import fnmatch
+
+    pattern = "*.tavern.yaml"
+
+    ret = {}
+
+    for path, subdirs, files in os.walk(root_dir):
+        for name in files:
+            if fnmatch(name, pattern):
+                test_path = os.path.join(path, name)
+                ret[test_path.replace(".", "_").replace("-", "_").replace("/", "_")] = test_path
+    return ret
+
+def class_to_path(class_name, class_to_path_dic):
+    from fnmatch import fnmatch
+    for c, p in class_to_path_dic.items():
+        if fnmatch(c, "*" + class_name):
+            return p
+    return None
+
+if __name__ == '__main__':
+    above_treshold = False
+    import argparse
+    parser = argparse.ArgumentParser()
+    parser.add_argument("path_to_test_dir", type = str, help = "Path to test directory for given json benchmark file")
+    parser.add_argument("json_file", type = str, help = "Path to benchmark json file")
+    parser.add_argument("--time-threshold", dest="time_threshold", type=float, default=1.0, help="Time threshold for test execution time, tests with execution time greater than threshold will be marked on red.")
+    args = parser.parse_args()
+    html_file, _ = os.path.splitext(args.json_file)
+    html_file = "tavern_benchmark_report_" + html_file + ".html"
+    class_to_path_dic = make_class_path_dict(args.path_to_test_dir)
+    with open(html_file, "w") as ofile:
+        ofile.write("<html>\n")
+        ofile.write("  <head>\n")
+        ofile.write("    <style>\n")
+        ofile.write("      table, th, td {\n")
+        ofile.write("        border: 1px solid black;\n")
+        ofile.write("        border-collapse: collapse;\n")
+        ofile.write("      }\n")
+        ofile.write("      th, td {\n")
+        ofile.write("        padding: 15px;\n")
+        ofile.write("      }\n")
+        ofile.write("    </style>\n")
+        ofile.write("  </head>\n")
+        ofile.write("  <body>\n")
+        ofile.write("    <table>\n")
+        ofile.write("      <tr><th>Test name</th><th>Time [s]</th></tr>\n")
+        json_data = None
+        with open(args.json_file, "r") as json_file:
+            json_data = load(json_file)
+        for benchmark in json_data['benchmarks']:
+            if float(benchmark['stats']['mean']) > args.time_threshold:
+                ofile.write("      <tr><td>{}<br/>Parameters: {}</td><td bgcolor=\"red\">{:.4f}</td></tr>\n".format(benchmark['name'], get_request_from_yaml(class_to_path(benchmark['name'][5:], class_to_path_dic)), benchmark['stats']['mean']))
+                above_treshold = True
+            else:
+                ofile.write("      <tr><td>{}</td><td>{:.4f}</td></tr>\n".format(benchmark['name'], benchmark['stats']['mean']))
+        ofile.write("    </table>\n")
+        ofile.write("  </body>\n")
+        ofile.write("</html>\n")
+    if above_treshold:
+        exit(1)
+    exit(0)
diff --git a/tests/tests_api b/tests/tests_api
index 7bd064bf665df199064f318b41e7a2afa96e6c1f..380a6a4a2d478c055f25c0a5bf2e3c246c407916 160000
--- a/tests/tests_api
+++ b/tests/tests_api
@@ -1 +1 @@
-Subproject commit 7bd064bf665df199064f318b41e7a2afa96e6c1f
+Subproject commit 380a6a4a2d478c055f25c0a5bf2e3c246c407916
diff --git a/tox.ini b/tox.ini
index f475a0aa96a3b70954e319a7fe560131bebcf2eb..eb808212162539fbde0384cedea0860e2b8dbc40 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,7 +1,19 @@
 [tox]
-envlist = py36
+envlist = py36, tavern, benchmark
 
 [testenv]
+deps = 
+  pytest
+
+[testenv:benchmark]
+deps =
+  {[testenv]deps}
+  pytest-benchmark
+  requests
+
+commands = pytest {posargs}
+
+[testenv:tavern]
 setenv = 
   PYTHONPATH = {toxinidir}/tests/tests_api/hivemind/tavern:{env:PYTHONPATH:}
 
@@ -12,7 +24,7 @@ passenv =
 changedir = tests/tests_api/hivemind/tavern
 
 deps = 
-  pytest
+  {[testenv]deps}
   pytest-cov
   pytest-pylint
   pytest-asyncio