diff --git a/monkey/monkey_island.py b/monkey/monkey_island.py
index b3b74e6b3..cd452066c 100644
--- a/monkey/monkey_island.py
+++ b/monkey/monkey_island.py
@@ -1,3 +1,7 @@
+from gevent import monkey as gevent_monkey
+
+gevent_monkey.patch_all()
+
 from monkey_island.cc.main import main
 
 
@@ -5,8 +9,9 @@ def parse_cli_args():
     import argparse
     parser = argparse.ArgumentParser(description="Infection Monkey Island CnC Server. See https://infectionmonkey.com")
     parser.add_argument("-s", "--setup-only", action="store_true",
-                        help="Pass this flag to cause the Island to setup and exit without actually starting. This is useful "
-                             "for preparing Island to boot faster later-on, so for compiling/packaging Islands.")
+                        help="Pass this flag to cause the Island to setup and exit without actually starting. "
+                             "This is useful for preparing Island to boot faster later-on, so for "
+                             "compiling/packaging Islands.")
     args = parser.parse_args()
     return args.setup_only
 
diff --git a/monkey/monkey_island/cc/main.py b/monkey/monkey_island/cc/main.py
index 610681034..cf58f48c5 100644
--- a/monkey/monkey_island/cc/main.py
+++ b/monkey/monkey_island/cc/main.py
@@ -6,6 +6,8 @@ from pathlib import Path
 from threading import Thread
 
 # Add the monkey_island directory to the path, to make sure imports that don't start with "monkey_island." work.
+from gevent.pywsgi import WSGIServer
+
 MONKEY_ISLAND_DIR_BASE_PATH = str(Path(__file__).parent.parent)
 if str(MONKEY_ISLAND_DIR_BASE_PATH) not in sys.path:
     sys.path.insert(0, MONKEY_ISLAND_DIR_BASE_PATH)
@@ -46,9 +48,6 @@ def main(should_setup_only=False):
 
 
 def start_island_server(should_setup_only):
-    from tornado.httpserver import HTTPServer
-    from tornado.ioloop import IOLoop
-    from tornado.wsgi import WSGIContainer
 
     mongo_url = os.environ.get('MONGO_URL', env_singleton.env.get_mongo_url())
     wait_for_mongo_db_server(mongo_url)
@@ -69,12 +68,11 @@ def start_island_server(should_setup_only):
     if env_singleton.env.is_debug():
         app.run(host='0.0.0.0', debug=True, ssl_context=(crt_path, key_path))
     else:
-        http_server = HTTPServer(WSGIContainer(app),
-                                 ssl_options={'certfile': os.environ.get('SERVER_CRT', crt_path),
-                                              'keyfile': os.environ.get('SERVER_KEY', key_path)})
-        http_server.listen(env_singleton.env.get_island_port())
+        http_server = WSGIServer(('0.0.0.0', env_singleton.env.get_island_port()), app,
+                                 certfile=os.environ.get('SERVER_CRT', crt_path),
+                                 keyfile=os.environ.get('SERVER_KEY', key_path))
         log_init_info()
-        IOLoop.instance().start()
+        http_server.serve_forever()
 
 
 def log_init_info():
diff --git a/monkey/monkey_island/cc/services/reporting/report_generation_synchronisation.py b/monkey/monkey_island/cc/services/reporting/report_generation_synchronisation.py
index f2fa11c89..990df24e4 100644
--- a/monkey/monkey_island/cc/services/reporting/report_generation_synchronisation.py
+++ b/monkey/monkey_island/cc/services/reporting/report_generation_synchronisation.py
@@ -1,5 +1,6 @@
 import logging
-import threading
+
+from gevent.lock import BoundedSemaphore
 
 logger = logging.getLogger(__name__)
 
@@ -7,9 +8,9 @@ logger = logging.getLogger(__name__)
 # Report generation can be quite slow if there is a lot of data, and the UI queries the Root service often; without
 # the locks, these requests would accumulate, overload the server, eventually causing it to crash.
 logger.debug("Initializing report generation locks.")
-__report_generating_lock = threading.Semaphore()
-__attack_report_generating_lock = threading.Semaphore()
-__regular_report_generating_lock = threading.Semaphore()
+__report_generating_lock = BoundedSemaphore()
+__attack_report_generating_lock = BoundedSemaphore()
+__regular_report_generating_lock = BoundedSemaphore()
 
 
 def safe_generate_reports():
diff --git a/monkey/monkey_island/cc/ui/webpack.config.js b/monkey/monkey_island/cc/ui/webpack.config.js
index 975e914ce..b1d8b5218 100644
--- a/monkey/monkey_island/cc/ui/webpack.config.js
+++ b/monkey/monkey_island/cc/ui/webpack.config.js
@@ -75,7 +75,8 @@ module.exports = {
     proxy: {
       '/api': {
         target: 'https://localhost:5000',
-        secure: false
+        secure: false,
+        changeOrigin: true
       }
     }
   }
diff --git a/monkey/monkey_island/requirements.txt b/monkey/monkey_island/requirements.txt
index cef10fcb7..f1e80161c 100644
--- a/monkey/monkey_island/requirements.txt
+++ b/monkey/monkey_island/requirements.txt
@@ -8,6 +8,7 @@ botocore==1.17.54
 cffi>=1.8,!=1.11.3
 dpath>=2.0
 flask>=1.1
+gevent>=20.9.0
 ipaddress>=1.0.23
 jsonschema==3.2.0
 mongoengine==0.20
@@ -20,7 +21,6 @@ requests>=2.24
 ring>=0.7.3
 stix2>=2.0.2
 six>=1.13.0
-tornado>=6.0.4
 tqdm>=4.47
 virtualenv>=20.0.26
 werkzeug>=1.0.1