diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 428f6c41b4b2355589675dfe291d2dfa5e3d4038..04be27bab04f8d7f4db2cea7f3cce7f76cc2e3d9 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -15,6 +15,7 @@ import watch_dirs
 class SimpleConfig(object):
   def __init__(self, config):
     self.build_config = config
+    self.maxjobs = 32 * multiprocessing.cpu_count()
 
   def run_command(self, binary):
     return [binary]
@@ -22,11 +23,13 @@ class SimpleConfig(object):
 
 # ValgrindConfig: compile with some CONFIG=config, but use valgrind to run
 class ValgrindConfig(object):
-  def __init__(self, config):
+  def __init__(self, config, tool):
     self.build_config = config
+    self.tool = tool
+    self.maxjobs = 4 * multiprocessing.cpu_count()
 
   def run_command(self, binary):
-    return ['valgrind', binary]
+    return ['valgrind', binary, '--tool=%s' % self.tool]
 
 
 # different configurations we can run under
@@ -37,7 +40,8 @@ _CONFIGS = {
   'msan': SimpleConfig('msan'),
   'asan': SimpleConfig('asan'),
   'gcov': SimpleConfig('gcov'),
-  'valgrind': ValgrindConfig('dbg'),
+  'memcheck': ValgrindConfig('dbg', 'memcheck'),
+  'helgrind': ValgrindConfig('dbg', 'helgrind')
   }
 
 
@@ -81,14 +85,18 @@ def _build_and_run(check_cancelled):
     return 1
 
   # run all the tests
-  if not jobset.run((
-      config.run_command(x)
-      for config in run_configs
-      for filt in filters
-      for x in itertools.chain.from_iterable(itertools.repeat(
-          glob.glob('bins/%s/%s_test' % (
-              config.build_config, filt)),
-          runs_per_test))), check_cancelled):
+  if not jobset.run(
+      itertools.ifilter(
+          lambda x: x is not None, (
+              config.run_command(x)
+              for config in run_configs
+              for filt in filters
+              for x in itertools.chain.from_iterable(itertools.repeat(
+                  glob.glob('bins/%s/%s_test' % (
+                      config.build_config, filt)),
+                  runs_per_test)))),
+              check_cancelled,
+              maxjobs=min(c.maxjobs for c in run_configs)):
     return 2
 
   return 0