diff --git a/py_wake/tests/test_wind_farm_models/test_memory_usage.py b/py_wake/tests/test_wind_farm_models/test_memory_usage.py
new file mode 100644
index 0000000000000000000000000000000000000000..acc78590b3dd9fdafdd30d734047fc0886a989e1
--- /dev/null
+++ b/py_wake/tests/test_wind_farm_models/test_memory_usage.py
@@ -0,0 +1,61 @@
+from py_wake.examples.data.hornsrev1 import V80, Hornsrev1Site, wt16_x, wt16_y
+from py_wake.deficit_models.noj import NOJ, NOJDeficit
+import os
+import psutil
+import matplotlib.pyplot as plt
+import numpy as np
+import gc
+from py_wake.wind_farm_models.engineering_models import All2AllIterative
+import memory_profiler
+from py_wake.tests import npt
+import pytest
+
+
+def get_memory_usage():
+    pid = os.getpid()
+    python_process = psutil.Process(pid)
+    return python_process.memory_info()[0] / 1024**2
+
+
+def test_memory_usage():
+    if os.name == 'posix':
+        pytest.skip('Memory usage seems not to work on linux')
+    gc.collect()
+    initial_mem_usage = get_memory_usage()
+    wt = V80()
+    site = Hornsrev1Site()
+    x, y = site.initial_position.T
+
+    for wfm, mem_min, mem_max in [(NOJ(site, wt), 65, 90),
+                                  (All2AllIterative(site, wt, wake_deficitModel=NOJDeficit()), 530, 540)]:
+        mem_usage, _ = memory_profiler.memory_usage(
+            (wfm, (x, y), {'wd': np.arange(0, 360, 4)}), interval=0.001, max_usage=True, retval=True)
+
+        mem_usage -= initial_mem_usage
+        print(initial_mem_usage, mem_usage)
+        assert mem_min < mem_usage < mem_max, (initial_mem_usage, mem_usage)
+
+    return
+
+
+def test_memory_leak():
+
+    N = 10
+
+    wt = V80()
+    site = Hornsrev1Site()
+
+    wfm_lst = [NOJ(site, wt), All2AllIterative(site, wt, wake_deficitModel=NOJDeficit())]
+    memory_usage = np.zeros((len(wfm_lst), N))
+    for i, wfm in enumerate(wfm_lst):
+        memory_usage[i, 0] = get_memory_usage()
+        for j in range(1, N):
+            wfm(wt16_x, wt16_y, ws=10, wd=np.arange(0, 360, 30))
+            gc.collect()
+            memory_usage[i, j] = get_memory_usage()
+    npt.assert_array_less(memory_usage - memory_usage[:, :1], 1)  # at most 1mb more than initial usage
+    if 0:
+        for i, wfm in enumerate(wfm_lst):
+            plt.plot(memory_usage[i], label=str(wfm.__class__.__name__))
+        plt.legend()
+        plt.show()
diff --git a/setup.py b/setup.py
index 6a26a34574b04520214796f27345cac26fe4a512..a6d75acdef99ccbfd21f331f3cae9d79d0a74524 100644
--- a/setup.py
+++ b/setup.py
@@ -57,6 +57,7 @@ setup(name='py_wake',
               'pytest',  # for testing
               'pytest-cov',  # for calculating coverage
               'psutil',  # memory profiling
+              'memory_profiler',  # memory profiling
               'sphinx',  # generating documentation
               'sphinx_rtd_theme',  # docs theme
               'line_profiler',  # to check speed