diff --git a/README.md b/README.md
index 30b3966..04e017b 100644
--- a/README.md
+++ b/README.md
@@ -210,7 +210,7 @@ Python 3.6+ decorators including
 
         - Values can persist to disk and be reloaded when memoize is initialized again.
 
-            @memoize(db=True)
+            @memoize(db_path=Path.home() / '.memoize')
             def foo(a) -> Any: ...
 
             foo(1)  # Function actually called. Result cached.
@@ -219,34 +219,6 @@ Python 3.6+ decorators including
 
             foo(1)  # Function not called. Cached result returned.
 
-        - Be careful with 'db' and memoize values that don't hash consistently upon process restart.
-
-            class Foo:
-                @classmethod
-                @memoize(db=True)
-                def bar(cls, a) -> Any: ...
-
-            Foo.bar(1)  # Function actually called. Result cached.
-            Foo.bar(1)  # Function not called. Cached result returned.
-
-            # Process is restarted. Upon restart, the state of the memoize decorator is reloaded.
-
-            # Hash value of 'cls', is now different.
-            Foo.bar(1)  # Function actually called. Result cached.
-
-            # You can create a consistent hash key to avoid this.
-            class Foo:
-                @classmethod
-                @memoize(db=True, keygen=lambda cls, a: (f'{cls.__package__}:{cls.__name__}', a))
-                def bar(cls, a) -> Any: ...
-
-        - Alternative location of 'db' can also be given as pathlib.Path or str.
-            @memoize(db=Path.home() / 'foo_memoize')
-            def foo() -> Any: ...
-
-            @memoize(db='~/bar_memoize')
-            def bar() -> Any: ...
-
 ## rate
     Function decorator that rate limits the number of calls to function.
 
diff --git a/atools/_memoize_decorator.py b/atools/_memoize_decorator.py
index 4cc93e3..9412f92 100644
--- a/atools/_memoize_decorator.py
+++ b/atools/_memoize_decorator.py
@@ -533,7 +533,7 @@ class _Memoize:
 
         - Values can persist to disk and be reloaded when memoize is initialized again.
 
-            @memoize(db=True)
+            @memoize(db_path=Path.home() / '.memoize')
             def foo(a) -> Any: ...
 
             foo(1)  # Function actually called. Result cached.
@@ -541,53 +541,24 @@ class _Memoize:
             # Process is restarted. Upon restart, the state of the memoize decorator is reloaded.
 
             foo(1)  # Function not called. Cached result returned.
-
-        - Be careful with 'db' and memoize values that don't hash consistently upon process restart.
-
-            class Foo:
-                @classmethod
-                @memoize(db=True)
-                def bar(cls, a) -> Any: ...
-
-            Foo.bar(1)  # Function actually called. Result cached.
-            Foo.bar(1)  # Function not called. Cached result returned.
-
-            # Process is restarted. Upon restart, the state of the memoize decorator is reloaded.
-
-            # Hash value of 'cls', is now different.
-            Foo.bar(1)  # Function actually called. Result cached.
-
-            # You can create a consistent hash key to avoid this.
-            class Foo:
-                @classmethod
-                @memoize(db=True, keygen=lambda cls, a: (f'{cls.__package__}:{cls.__name__}', a))
-                def bar(cls, a) -> Any: ...
-
-        - Alternative location of 'db' can also be given as pathlib.Path or str.
-            @memoize(db=Path.home() / 'foo_memoize')
-            def foo() -> Any: ...
-
-            @memoize(db='~/bar_memoize')
-            def bar() -> Any: ...
     """
 
-    _default_db_path = Path.home() / '.memoize'
     _all_decorators = WeakSet()
 
     @staticmethod
     def __call__(
             _decoratee: Optional[Decoratee] = None,
             *,
-            db: Union[bool, Path, str] = False,
+            db_path: Optional[Path] = None,
             duration: Optional[Union[int, float, timedelta]] = None,
             keygen: Optional[Keygen] = None,
             size: Optional[int] = None,
     ):
         if _decoratee is None:
-            return partial(memoize, db=db, duration=duration, keygen=keygen, size=size)
+            return partial(memoize, db_path=db_path, duration=duration, keygen=keygen, size=size)
 
         if inspect.isclass(_decoratee):
-            assert not db, 'Class memoization not allowed with db.'
+            assert db_path is None, 'Class memoization not allowed with db.'
 
             class WrappedMeta(type(_decoratee)):
                 # noinspection PyMethodParameters
@@ -600,14 +571,7 @@ class _Memoize:
 
             return type(_decoratee.__name__, (Wrapped,), {'__doc__': _decoratee.__doc__})
 
-        if isinstance(db, (str, Path)):
-            db = connect(f'{db}')
-        elif isinstance(db, bool):
-            if db:
-                db = connect(f'{_Memoize._default_db_path}')
-            else:
-                db = None
-
+        db = connect(f'{db_path}') if db_path is not None else None
         duration = timedelta(seconds=duration) if isinstance(duration, (int, float)) else duration
         assert (duration is None) or (duration.total_seconds() > 0)
         assert (size is None) or (size > 0)
@@ -640,9 +604,5 @@ class _Memoize:
         for decorator in _Memoize._all_decorators:
             decorator.memoize.reset()
 
-    @staticmethod
-    def set_default_db_path(path: Union[Path, str]) -> None:
-        _Memoize._default_db_path = Path(f'{path}')
-
 
 memoize = _Memoize()
diff --git a/setup.py b/setup.py
index f27ee37..dd5f7eb 100644
--- a/setup.py
+++ b/setup.py
@@ -2,7 +2,7 @@ from setuptools import find_packages, setup
 
 setup(
     name='atools',
-    version='0.11.0',
+    version='0.12.0',
     packages=find_packages(),
     python_requires='>=3.6',
     url='https://github.com/cevans87/atools',

Remove `memoize.set_default_db_path` function
The `memoize.set_default_db_path` function is difficult to use correctly as is. It requires that you call the default before anyone using the decorator actually applies it. AKA, you have to call the function before importing any code that applies the memoize decorator. This is an unnatural way of doing things in Python and should be improved.

Instead, users should take advantage of `memoize(db=my_db_path)`. The argument doesn't need to be applied everywhere. Users can create their own package-specific memoize decorator with alternate default arguments very easily. For example

```python3
# file: my_persistent_memoize.py
from atools import memoize
from pathlib import Path as _Path

memoize_db = memoize(db=_Path.home() / '.my_alternate_db_location')
```
And now they can use this new memoize_db in their package.

```python3
# file: foo.py
from my_persistent_memoize import memoize_db

@memoize_db
async def foobar(): ...
```
diff --git a/test/test_memoize_decorator.py b/test/test_memoize_decorator.py
index 5172e1b..2ccc0ac 100644
--- a/test/test_memoize_decorator.py
+++ b/test/test_memoize_decorator.py
@@ -6,18 +6,15 @@ import atools._memoize_decorator as test_module
 from datetime import timedelta
 from pathlib import Path, PosixPath
 import pytest
-from sqlite3 import connect, Connection
+from sqlite3 import connect
 from tempfile import NamedTemporaryFile
-from typing import Callable, FrozenSet, Hashable, Iterable, Tuple, Union
-from unittest.mock import call, MagicMock, patch, PropertyMock
+from typing import Callable, FrozenSet, Hashable, Iterable, Tuple
+from unittest.mock import call, MagicMock, patch
 from weakref import ref
 
 
-def get_table_len(db) -> int:
-    if isinstance(db, bool):
-        db = connect(f'{memoize._default_db_path}')
-    elif isinstance(db, (Path, str)):
-        db = connect(f'{db}')
+def get_table_len(db_path: Path) -> int:
+    db = connect(f'{db_path}')
     # noinspection SqlResolve
     return len(db.execute("SELECT name FROM sqlite_master where type='table'").fetchall())
 
@@ -28,17 +25,10 @@ def async_lock() -> MagicMock:
         yield async_lock
 
 
-@pytest.fixture(params=[bool, connect, Path, str])
-def db(request) -> Union[bool, Connection, Path, str]:
+@pytest.fixture
+def db_path() -> Path:
     with NamedTemporaryFile() as f:
-        if request.param is bool:
-            with patch.object(
-                    type(memoize), '_default_db_path', new_callable=PropertyMock
-            ) as default_db_path:
-                default_db_path.return_value = Path(f.name)
-                yield True
-        else:
-            yield request.param(f.name)
+        yield Path(f.name)
 
 
 @pytest.fixture
@@ -629,29 +619,29 @@ async def test_keygen_awaits_awaitable_parts() -> None:
     )
 
 
-def test_db_creates_table_for_each_decorator(db: Union[bool, Connection, Path, str]) -> None:
+def test_db_creates_table_for_each_decorator(db_path: Path) -> None:
     
-    assert get_table_len(db) == 0
+    assert get_table_len(db_path) == 0
 
-    @memoize(db=db)
+    @memoize(db_path=db_path)
     def foo() -> None:
         ...
 
-    assert get_table_len(db) == 1
+    assert get_table_len(db_path) == 1
 
-    @memoize(db=db)
+    @memoize(db_path=db_path)
     def bar() -> None:
         ...
 
-    assert get_table_len(db) == 2
+    assert get_table_len(db_path) == 2
 
 
-def test_db_reloads_values_from_disk(db: Union[bool, Connection, Path, str]) -> None:
+def test_db_reloads_values_from_disk(db_path: Path) -> None:
     body = MagicMock()
     
     def foo() -> None:
 
-        @memoize(db=db)
+        @memoize(db_path=db_path)
         def foo_inner() -> None:
             body()
 
@@ -663,11 +653,11 @@ def test_db_reloads_values_from_disk(db: Union[bool, Connection, Path, str]) ->
     assert body.call_count == 1
 
 
-def test_reset_removes_values_on_disk(db: Union[bool, Connection, Path, str]) -> None:
+def test_reset_removes_values_on_disk(db_path: Path) -> None:
     body = MagicMock()
 
     def foo() -> None:
-        @memoize(db=db)
+        @memoize(db_path=db_path)
         def foo_inner() -> None:
             body()
 
@@ -680,11 +670,11 @@ def test_reset_removes_values_on_disk(db: Union[bool, Connection, Path, str]) ->
     assert body.call_count == 2
 
 
-def test_db_expires_memo(db: Union[bool, Connection, Path, str], time: MagicMock) -> None:
+def test_db_expires_memo(db_path: Path, time: MagicMock) -> None:
     body = MagicMock()
 
     def foo() -> None:
-        @memoize(db=db, duration=timedelta(days=1))
+        @memoize(db_path=db_path, duration=timedelta(days=1))
         def foo_inner() -> None:
             body()
 
@@ -698,11 +688,11 @@ def test_db_expires_memo(db: Union[bool, Connection, Path, str], time: MagicMock
     assert body.call_count == 2
 
 
-def test_db_memoizes_multiple_values(db: Union[bool, Connection, Path, str]) -> None:
+def test_db_memoizes_multiple_values(db_path: Path) -> None:
     body = MagicMock()
 
     def get_foo() -> Callable[[int], None]:
-        @memoize(db=db)
+        @memoize(db_path=db_path)
         def _foo(_i: int) -> None:
             body(_i)
 
@@ -717,11 +707,11 @@ def test_db_memoizes_multiple_values(db: Union[bool, Connection, Path, str]) ->
     assert len(foo.memoize) == 10
 
 
-def test_db_with_size_expires_lru(db: Union[bool, Connection, Path, str]) -> None:
+def test_db_with_size_expires_lru(db_path: Path) -> None:
     body = MagicMock()
 
     def foo(it: Iterable[int]) -> None:
-        @memoize(db=db, size=5)
+        @memoize(db_path=db_path, size=5)
         def foo_inner(_i: int) -> None:
             body(_i)
 
@@ -735,13 +725,13 @@ def test_db_with_size_expires_lru(db: Union[bool, Connection, Path, str]) -> Non
     
     
 def test_db_with_duration_expires_stale_values(
-        db: Union[bool, Connection, Path, str],
+        db_path: Path,
         time: MagicMock,
 ) -> None:
     body = MagicMock()
 
     def foo(it: Iterable[int]) -> None:
-        @memoize(db=db, duration=timedelta(hours=1))
+        @memoize(db_path=db_path, duration=timedelta(hours=1))
         def foo_inner(_i: int) -> None:
             body(_i)
 
@@ -761,11 +751,11 @@ def test_db_with_duration_expires_stale_values(
     assert body.call_count == 20
 
 
-def test_db_memoizes_frozenset(db: Union[bool, Connection, Path, str]) -> None:
+def test_db_memoizes_frozenset(db_path: Path) -> None:
     body = MagicMock()
 
     def foo() -> FrozenSet[int]:
-        @memoize(db=db)
+        @memoize(db_path=db_path)
         def foo_inner() -> FrozenSet[int]:
             body()
             return frozenset({1, 2, 3})
@@ -832,11 +822,11 @@ async def test_async_reset_call_resets_call() -> None:
     assert body.call_count == 11
 
 
-def test_reset_call_with_db_resets_call(db: Union[bool, Connection, Path, str]) -> None:
+def test_reset_call_with_db_resets_call(db_path: Path) -> None:
     body = MagicMock()
 
     def get_foo() -> Callable[[int], None]:
-        @memoize(db=db)
+        @memoize(db_path=db_path)
         def foo(_i: int) -> None:
             body(_i)
 
@@ -854,19 +844,6 @@ def test_reset_call_with_db_resets_call(db: Union[bool, Connection, Path, str])
     assert body.call_count == 11
 
 
-def test_set_default_db_path_uses_given_path() -> None:
-    with NamedTemporaryFile() as f, patch.object(type(memoize), '_default_db_path'):
-        memoize.set_default_db_path(f.name)
-
-        assert get_table_len(f.name) == 0
-
-        @memoize(db=True)
-        def foo() -> None:
-            ...
-
-        assert get_table_len(f.name) == 1
-
-
 @pytest.mark.asyncio
 async def test_async_keygen_can_return_non_tuple() -> None:
     body = MagicMock()
@@ -883,9 +860,9 @@ async def test_async_keygen_can_return_non_tuple() -> None:
     assert body.call_count == 1
 
 
-def test_db_can_return_type_of_callers_globals(db: Union[bool, Connection, Path, str]) -> None:
+def test_db_can_return_type_of_callers_globals(db_path: Path) -> None:
 
-    @memoize(db=db)
+    @memoize(db_path=db_path)
     def foo():
         return PosixPath.cwd()
 

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-asyncio pytest-cov
apt-get update apt-get install -y gcc
3.7
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
-e git+https://github.com/cevans87/atools.git@f3f59a757ba3894b68b1b49cb9860c989deacf5e#egg=atools
certifi @ file:///croot/certifi_1671487769961/work/certifi
coverage==7.2.7
exceptiongroup==1.2.2
frozendict==2.4.6
importlib-metadata==6.7.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.2.0
pytest==7.4.4
pytest-asyncio==0.21.2
pytest-cov==4.1.0
tomli==2.0.1
typing_extensions==4.7.1
zipp==3.15.0

name: atools
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2022.12.7=py37h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=22.3.1=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - coverage==7.2.7
      - exceptiongroup==1.2.2
      - frozendict==2.4.6
      - importlib-metadata==6.7.0
      - iniconfig==2.0.0
      - packaging==24.0
      - pluggy==1.2.0
      - pytest==7.4.4
      - pytest-asyncio==0.21.2
      - pytest-cov==4.1.0
      - tomli==2.0.1
      - typing-extensions==4.7.1
      - zipp==3.15.0
prefix: /opt/conda/envs/atools

test/test_memoize_decorator.py::test_db_creates_table_for_each_decorator test/test_memoize_decorator.py::test_db_reloads_values_from_disk test/test_memoize_decorator.py::test_reset_removes_values_on_disk test/test_memoize_decorator.py::test_db_expires_memo test/test_memoize_decorator.py::test_db_memoizes_multiple_values test/test_memoize_decorator.py::test_db_with_size_expires_lru test/test_memoize_decorator.py::test_db_with_duration_expires_stale_values test/test_memoize_decorator.py::test_db_memoizes_frozenset test/test_memoize_decorator.py::test_reset_call_with_db_resets_call test/test_memoize_decorator.py::test_db_can_return_type_of_callers_globals
test/test_memoize_decorator.py::test_zero_args test/test_memoize_decorator.py::test_class_function test/test_memoize_decorator.py::test_keyword_same_as_default test/test_memoize_decorator.py::test_async test/test_memoize_decorator.py::test_sync_size test/test_memoize_decorator.py::test_async_size test/test_memoize_decorator.py::test_sync_exception test/test_memoize_decorator.py::test_async_exception test/test_memoize_decorator.py::test_expire_current_call test/test_memoize_decorator.py::test_expire_old_call test/test_memoize_decorator.py::test_expire_old_item_does_not_expire_new test/test_memoize_decorator.py::test_expire_head_of_line_refresh_does_not_stop_eviction test/test_memoize_decorator.py::test_async_stops_thundering_herd test/test_memoize_decorator.py::test_size_le_zero_raises test/test_memoize_decorator.py::test_expire_le_zero_raises test/test_memoize_decorator.py::test_args_overlaps_kwargs_raises test/test_memoize_decorator.py::test_sync_reset_clears_cache test/test_memoize_decorator.py::test_async_reset_clears_cache test/test_memoize_decorator.py::test_works_with_property test/test_memoize_decorator.py::test_sync_locks_sync test/test_memoize_decorator.py::test_async_does_not_sync_lock test/test_memoize_decorator.py::test_async_locks_async test/test_memoize_decorator.py::test_sync_does_not_async_lock test/test_memoize_decorator.py::test_async_no_event_loop_does_not_raise test/test_memoize_decorator.py::test_memoizes_class test/test_memoize_decorator.py::test_memoizes_class_with_metaclass test/test_memoize_decorator.py::test_reset_all_resets_class_decorators test/test_memoize_decorator.py::test_reset_all_resets_function_decorators test/test_memoize_decorator.py::test_async_herd_waits_for_return test/test_memoize_decorator.py::test_memoize_does_not_stop_object_cleanup test/test_memoize_decorator.py::test_memoize_class_preserves_doc test/test_memoize_decorator.py::test_keygen_overrides_default test/test_memoize_decorator.py::test_keygen_awaits_awaitable_parts test/test_memoize_decorator.py::test_sync_reset_call_resets_one test/test_memoize_decorator.py::test_reset_call_before_expire_resets_one test/test_memoize_decorator.py::test_async_reset_call_resets_call test/test_memoize_decorator.py::test_async_keygen_can_return_non_tuple test/test_memoize_decorator.py::test_memoized_function_is_deletable test/test_memoize_decorator.py::test_keygen_works_with_default_kwargs test/test_memoize_decorator.py::test_sync_memo_lifetime_is_lte_arg_with_default_object_hash test/test_memoize_decorator.py::test_async_memo_lifetime_is_lte_arg_with_default_object_hash test/test_memoize_decorator.py::test_sync_memo_lifetime_is_lte_keygen_part_with_default_default_hash test/test_memoize_decorator.py::test_async_memo_lifetime_is_lte_keygen_part_with_default_default_hash test/test_memoize_decorator.py::test_sync_memo_lifetime_not_affected_by_arg_with_non_default_hash test/test_memoize_decorator.py::test_async_memo_lifetime_not_affected_by_arg_with_non_default_hash test/test_memoize_decorator.py::test_sync_memo_lifetime_lte_keygen_part_with_non_default_hash test/test_memoize_decorator.py::test_async_memo_lifetime_lte_keygen_part_with_non_default_hash
atools/_memoize_decorator.py README.md setup.py
atools/_memoize_decorator.py README.md setup.py