Skip to content

Users performance measurements ​

Measured locally on 2026-11-05, using production password costs (SM_TEST_REAL_PASSWORD_HASHING=1) and the installed fastapi-users 15.0.5. The baseline is the working tree before the password offload change.

A concurrent heartbeat sleeps for 5 ms and records the excess scheduling delay while the real manager/service performs the operation. The bulk case calls UserService.invite sequentially for 100 distinct accounts; it does not include HTTP parsing or email delivery. Fixtures use SQLite, so these measurements do not reproduce the review's Postgres/10k-user workload.

OperationBefore: worst loop lagAfter: worst loop lagBefore / after elapsed
100 sequential invitations254.1 ms5.1 ms27.273 / 27.387 s
Forgot-password fingerprint237.2 ms4.4 ms0.267 / 0.256 s

Offloading keeps the event loop responsive; it does not reduce the underlying password hashing work. These are single-run observations, not request latency percentiles. This sandbox did not reliably wake its event loop after cross-thread completions (even a standalone aiosqlite connection hung). Both runs used the same temporary test-runner shim that capped selector waits at 1 ms; application code and hashing costs were unchanged by the shim.

Run the opt-in measurements on a normal local environment:

sh
SM_TEST_REAL_PASSWORD_HASHING=1 uv run pytest \
  modules/users/tests/test_users_password_offload.py \
  -k real_hashing -q -s -p no:cacheprovider

The ordinary targeted regressions check crypto thread identity independently of timing, reset-token reuse rejection, and that database execution stays on the event-loop thread. Existing credential-revocation and password-policy tests cover the reset's transaction semantics.

For admin summaries, regressions record SQL execution and require zero new queries on repeated state-count and role-option reads within the TTL. They also cover expiry, local eviction when a user/role/membership write commits, one explicit users.admin_summary publish per admin write method after commit (none on rollback, none for login or lockout writes), remote invalidation, invalidation racing a cache fill, and role projections that do not instantiate ORM rows. DTO construction is checked without invoking SQLModel input validation.

Released under the MIT License.