diff --git a/changelog.d/8569.misc b/changelog.d/8569.misc
new file mode 100644
index 000000000..3b6e0625e
--- /dev/null
+++ b/changelog.d/8569.misc
@@ -0,0 +1,1 @@
+Fix mypy not properly checking across the codebase, additionally, fix a typing assertion error in `handlers/auth.py`.
\ No newline at end of file
diff --git a/changelog.d/8589.removal b/changelog.d/8589.removal
new file mode 100644
index 000000000..b80f29d6b
--- /dev/null
+++ b/changelog.d/8589.removal
@@ -0,0 +1,1 @@
+Drop unused `device_max_stream_id` table.
diff --git a/changelog.d/8591.misc b/changelog.d/8591.misc
new file mode 100644
index 000000000..8f16bc3e7
--- /dev/null
+++ b/changelog.d/8591.misc
@@ -0,0 +1,1 @@
+ Move metric registration code down into `LruCache`.
diff --git a/synapse/handlers/auth.py b/synapse/handlers/auth.py
index 1d1ddc224..8619fbb98 100644
--- a/synapse/handlers/auth.py
+++ b/synapse/handlers/auth.py
@@ -1122,20 +1122,22 @@ class AuthHandler(BaseHandler):
             Whether self.hash(password) == stored_hash.
         """
 
-        def _do_validate_hash():
+        def _do_validate_hash(checked_hash: bytes):
             # Normalise the Unicode in the password
             pw = unicodedata.normalize("NFKC", password)
 
             return bcrypt.checkpw(
                 pw.encode("utf8") + self.hs.config.password_pepper.encode("utf8"),
-                stored_hash,
+                checked_hash,
             )
 
         if stored_hash:
             if not isinstance(stored_hash, bytes):
                 stored_hash = stored_hash.encode("ascii")
 
-            return await defer_to_thread(self.hs.get_reactor(), _do_validate_hash)
+            return await defer_to_thread(
+                self.hs.get_reactor(), _do_validate_hash, stored_hash
+            )
         else:
             return False
 
diff --git a/synapse/storage/databases/main/schema/delta/58/21drop_device_max_stream_id.sql b/synapse/storage/databases/main/schema/delta/58/21drop_device_max_stream_id.sql
new file mode 100644
index 000000000..01ea6eddc
--- /dev/null
+++ b/synapse/storage/databases/main/schema/delta/58/21drop_device_max_stream_id.sql
@@ -0,0 +1,1 @@
+DROP TABLE device_max_stream_id;
diff --git a/synapse/util/caches/lrucache.py b/synapse/util/caches/lrucache.py
index 3b471d8fd..60bb6ff64 100644
--- a/synapse/util/caches/lrucache.py
+++ b/synapse/util/caches/lrucache.py
@@ -124,6 +124,10 @@ class LruCache(Generic[KT, VT]):
         else:
             self.max_size = int(max_size)
 
+        # register_cache might call our "set_cache_factor" callback; there's nothing to
+        # do yet when we get resized.
+        self._on_resize = None  # type: Optional[Callable[[],None]]
+
         if cache_name is not None:
             metrics = register_cache(
                 "lru_cache",
@@ -332,7 +336,10 @@ class LruCache(Generic[KT, VT]):
             return key in cache
 
         self.sentinel = object()
+
+        # make sure that we clear out any excess entries after we get resized.
         self._on_resize = evict
+
         self.get = cache_get
         self.set = cache_set
         self.setdefault = cache_set_default
@@ -383,6 +390,7 @@ class LruCache(Generic[KT, VT]):
         new_size = int(self._original_max_size * factor)
         if new_size != self.max_size:
             self.max_size = new_size
-            self._on_resize()
+            if self._on_resize:
+                self._on_resize()
             return True
         return False
diff --git a/tox.ini b/tox.ini
index 4d132eff4..6d0815378 100644
--- a/tox.ini
+++ b/tox.ini
@@ -158,7 +158,6 @@ commands=
     coverage html
 
 [testenv:mypy]
-skip_install = True
 deps =
     {[base]deps}
     mypy==0.782

diff --git a/tests/util/test_lrucache.py b/tests/util/test_lrucache.py
index f12834eda..a739a6aaa 100644
--- a/tests/util/test_lrucache.py
+++ b/tests/util/test_lrucache.py
@@ -19,7 +19,8 @@ from mock import Mock
 from synapse.util.caches.lrucache import LruCache
 from synapse.util.caches.treecache import TreeCache
 
-from .. import unittest
+from tests import unittest
+from tests.unittest import override_config
 
 
 class LruCacheTestCase(unittest.HomeserverTestCase):
@@ -83,6 +84,11 @@ class LruCacheTestCase(unittest.HomeserverTestCase):
         cache.clear()
         self.assertEquals(len(cache), 0)
 
+    @override_config({"caches": {"per_cache_factors": {"mycache": 10}}})
+    def test_special_size(self):
+        cache = LruCache(10, "mycache")
+        self.assertEqual(cache.max_size, 100)
+
 
 class LruCacheCallbacksTestCase(unittest.HomeserverTestCase):
     def test_get(self):

AttributeError: 'LruCache' object has no attribute '_on_resize'
I'm getting the following after updating `a9a8f2972..85c56445f`

```
2020-10-19 13:52:34,985 - synapse.federation.federation_server - 927 - ERROR - PUT-181 - Failed to handle edu 'm.typing'
Traceback (most recent call last):
  File "/home/erikj/synapse/synapse/federation/federation_server.py", line 923, in on_edu
    await handler(origin, content)
  File "/home/erikj/synapse/synapse/handlers/typing.py", line 328, in _recv_edu
    users = await self.store.get_users_in_room(room_id)
  File "/home/erikj/synapse/synapse/util/caches/descriptors.py", line 153, in __get__
    if expected_thread is not threading.current_thread():
  File "/home/erikj/synapse/synapse/util/caches/deferred_cache.py", line 93, in __init__
  File "/home/erikj/synapse/synapse/util/caches/lrucache.py", line 128, in __init__
  File "/home/erikj/synapse/synapse/util/caches/__init__.py", line 120, in register_cache
    metric_name = "cache_%s_%s" % (cache_type, cache_name)
  File "/home/erikj/synapse/synapse/config/cache.py", line 83, in add_resizable_cache
    properties.resize_all_caches_func()
  File "/home/erikj/synapse/synapse/config/cache.py", line 208, in resize_all_caches
    callback(new_factor)
  File "/home/erikj/synapse/synapse/util/caches/lrucache.py", line 386, in set_cache_factor
AttributeError: 'LruCache' object has no attribute '_on_resize'
```
tests/util/test_lrucache.py::LruCacheTestCase::test_special_size tests/util/test_lrucache.py::LruCacheCallbacksTestCase::test_clear
tests/util/test_lrucache.py::LruCacheTestCase::test_clear tests/util/test_lrucache.py::LruCacheTestCase::test_del_multi tests/util/test_lrucache.py::LruCacheTestCase::test_eviction tests/util/test_lrucache.py::LruCacheTestCase::test_get_set tests/util/test_lrucache.py::LruCacheTestCase::test_pop tests/util/test_lrucache.py::LruCacheTestCase::test_setdefault tests/util/test_lrucache.py::LruCacheCallbacksTestCase::test_del_multi tests/util/test_lrucache.py::LruCacheCallbacksTestCase::test_eviction tests/util/test_lrucache.py::LruCacheCallbacksTestCase::test_get tests/util/test_lrucache.py::LruCacheCallbacksTestCase::test_multi_get tests/util/test_lrucache.py::LruCacheCallbacksTestCase::test_pop tests/util/test_lrucache.py::LruCacheCallbacksTestCase::test_set tests/util/test_lrucache.py::LruCacheSizedTestCase::test_evict