diff --git a/plot_latency b/plot_latency
new file mode 100755
index 000000000..99224f515
--- /dev/null
+++ b/plot_latency
@@ -0,0 +1,78 @@
+#!/usr/bin/env python3
+
+import matplotlib
+matplotlib.use('Agg')
+import matplotlib.pyplot as plt
+import numpy as np
+import json
+from argparse import ArgumentParser
+
+"""
+Plots graph of latencies of memgraph and neo4j. Takes paths to
+json of latencies as arguments.
+"""
+
+def main():
+    argp = ArgumentParser(description=__doc__)
+    argp.add_argument('--memgraph-latency',
+                      help='Path to the json of memgraph latency')
+    argp.add_argument('--neo4j-latency',
+                      help='Path to the json of neo4j latency')
+    args = argp.parse_args()
+   
+    fig = plt.gcf()
+    fig.set_size_inches(10, 16)
+ 
+    with open(args.neo4j_latency) as json_file:
+        json_neo = json.load(json_file)
+
+    with open(args.memgraph_latency) as json_file:
+        json_mem = json.load(json_file)
+
+
+    tests_num = 0
+    time_list_neo = []
+    time_list_mem = []
+    max_time = 0
+
+    for key in json_mem['data']:
+        if json_neo['data'][key]['status'] == "passed" and \
+                json_mem['data'][key]['status'] == 'passed':
+            time_neo = json_neo['data'][key]['execution_time']
+            time_mem = json_mem['data'][key]['execution_time']
+            max_time = max(max_time, time_neo, time_mem)
+
+    offset = 0.01 * max_time
+
+    for key in json_mem['data']:
+        if json_neo['data'][key]['status'] == "passed" and \
+                json_mem['data'][key]['status'] == 'passed':
+            time_neo = json_neo['data'][key]['execution_time']
+            time_mem = json_mem['data'][key]['execution_time']
+            time_list_neo.append(time_neo)
+            time_list_mem.append(time_mem)
+            tests_num += 1
+
+            if time_neo < time_mem:
+                plt.plot((time_mem, time_neo), (tests_num, tests_num), color='red',
+                        label=key, lw=0.3)
+            else:
+                plt.plot((time_mem, time_neo), (tests_num, tests_num), color='green',
+                        label=key, lw=0.3)
+
+            ratio = '%.2f' % (max(time_neo, time_mem) / min(time_neo, time_mem))
+            plt.text(max(time_mem, time_neo) + offset, tests_num, key + " ---> " + \
+                     ratio + "x", size=1)
+
+    x = range(1, tests_num + 1)
+
+    plt.plot(time_list_mem, x, marker='o', markerfacecolor='orange', color='orange',
+            linestyle='', markersize=0.5)
+    plt.plot(time_list_neo, x, marker='o', markerfacecolor='blue', color='blue',
+            linestyle='', markersize=0.5)
+
+    plt.margins(0.1, 0.01)
+    plt.savefig("latency_graph.png", dpi=2000)
+
+if __name__ == '__main__':
+    main()
diff --git a/tck_engine/environment.py b/tck_engine/environment.py
index 2ca4cbf4b..c0b6b3dd5 100644
--- a/tck_engine/environment.py
+++ b/tck_engine/environment.py
@@ -3,6 +3,7 @@ import datetime
 import time
 import json
 import sys
+import os
 from steps.test_parameters import TestParameters
 from neo4j.v1 import GraphDatabase, basic_auth
 from steps.graph_properties import GraphProperties
@@ -10,13 +11,31 @@ from test_results import TestResults
 
 test_results = TestResults()
 
+"""
+Executes before every step. Checks if step is execution
+step and sets context variable to true if it is.
+"""
+def before_step(context, step):
+    context.execution_step = False
+    if step.name == "executing query":
+        context.execution_step = True
 
-def before_scenario(context, step):
+
+"""
+Executes before every scenario. Initializes test parameters,
+graph properties, exception and test execution time.
+"""
+def before_scenario(context, scenario):
     context.test_parameters = TestParameters()
     context.graph_properties = GraphProperties()
     context.exception = None
+    context.execution_time = None
 
 
+"""
+Executes after every scenario. Pauses execution if flags are set.
+Adds execution time to latency dict if it is not None.
+"""
 def after_scenario(context, scenario):
     test_results.add_test(scenario.status)
     if context.config.single_scenario or \
@@ -24,32 +43,50 @@ def after_scenario(context, scenario):
         print("Press enter to continue")
         sys.stdin.readline()
 
+    if context.execution_time is not None:
+        context.js['data'][scenario.name] = {
+            "execution_time": context.execution_time, "status": scenario.status
+        }
 
+
+"""
+Executes after every feature. If flag is set, pauses before
+executing next scenario.
+"""
 def after_feature(context, feature):
     if context.config.single_feature:
         print("Press enter to continue")
         sys.stdin.readline()
 
 
+"""
+Executes before running tests. Initializes driver and latency
+dict and creates needed directories.
+"""
 def before_all(context):
+    timestamp = datetime.datetime.fromtimestamp(time.time()).strftime("%Y_%m_%d__%H_%M_%S")
+    latency_file = "latency/" + context.config.database + "/" + \
+        get_test_suite(context) + "/" + timestamp + ".json"
+    if not os.path.exists(os.path.dirname(latency_file)):
+        os.makedirs(os.path.dirname(latency_file))
     context.driver = create_db_driver(context)
+    context.latency_file = latency_file
+    context.js = dict()
+    context.js["metadata"] = dict()
+    context.js["metadata"]["execution_time_unit"] = "seconds"
+    context.js["data"] = dict()
     set_logging(context)
 
 
+"""
+Executes when testing is finished. Creates JSON files of test latency
+and test results.
+"""
 def after_all(context):
     context.driver.close()
+    timestamp = datetime.datetime.fromtimestamp(time.time()).strftime("%Y_%m_%d__%H_%M")
 
-    ts = time.time()
-    timestamp = datetime.datetime.fromtimestamp(ts).strftime("%Y_%m_%d__%H_%M")
-
-    root = context.config.root
-
-    if root.endswith("/"):
-        root = root[0:len(root) - 1]
-    if root.endswith("features"):
-        root = root[0: len(root) - len("features") - 1]
-
-    test_suite = root.split('/')[-1]
+    test_suite = get_test_suite(context)
     file_name = context.config.output_folder + timestamp + \
         "-" + context.config.database + "-" + test_suite + ".json"
 
@@ -59,13 +96,40 @@ def after_all(context):
     with open(file_name, 'w') as f:
         json.dump(js, f)
 
+    with open(context.latency_file, "a") as f:
+            json.dump(context.js, f)
 
+
+"""
+Returns test suite from a test root folder.
+If test root is a feature file, name of file is returned without
+.feature extension.
+"""
+def get_test_suite(context):
+    root = context.config.root
+
+    if root.endswith("/"):
+        root = root[0:len(root) - 1]
+    if root.endswith("features"):
+        root = root[0: len(root) - len("features") - 1]
+
+    test_suite = root.split('/')[-1]
+
+    return test_suite
+
+
+"""
+Initializes log and sets logging level to debug.
+"""
 def set_logging(context):
     logging.basicConfig(level="DEBUG")
     log = logging.getLogger(__name__)
     context.log = log
 
 
+"""
+Creates database driver and returns it.
+"""
 def create_db_driver(context):
     uri = context.config.database_uri
     auth_token = basic_auth(
diff --git a/tck_engine/steps/database.py b/tck_engine/steps/database.py
index 770d1d354..6e71f297e 100644
--- a/tck_engine/steps/database.py
+++ b/tck_engine/steps/database.py
@@ -1,3 +1,5 @@
+import time
+
 def query(q, context, params={}):
     """
     Function used to execute query on database. Query results are
@@ -16,6 +18,7 @@ def query(q, context, params={}):
     if (context.config.database == "neo4j" or
         context.config.database == "memgraph"):
         session = context.driver.session()
+        start = time.time()
         try:
             # executing query
             results = session.run(q, params)
@@ -40,6 +43,10 @@ def query(q, context, params={}):
             context.exception = e
             context.log.info('%s', str(e))
         finally:
+            end = time.time()
+            if context.execution_step is not None and \
+                    context.execution_step:
+                context.execution_time = end - start
             session.close()
     return results_list
 
diff --git a/tck_engine/tests/memgraph_V1/features/functions.feature b/tck_engine/tests/memgraph_V1/features/functions.feature
index ec92bb97e..334e8f344 100644
--- a/tck_engine/tests/memgraph_V1/features/functions.feature
+++ b/tck_engine/tests/memgraph_V1/features/functions.feature
@@ -598,7 +598,7 @@ Feature: Functions
 
     Scenario: Keys test:
         Given an empty graph
-        And having executed:
+        When executing query:
             """
             CREATE (n{true: 123, a: null, b: 'x', null: 1}) RETURN KEYS(n) AS a
             """