Skip to content

perf(users): password hashing off the event loop; cached admin user summary - #844

Merged
antosubash merged 8 commits into
mainfrom
fix/s15-perf-users
Nov 5, 2026
Merged

antosubash merged 8 commits into
mainfrom
fix/s15-perf-users

Conversation

@antosubash

Copy link
Copy Markdown
Owner

Performance fix for the users module (local performance review, 2026-11-05).

Password hashing off the event loop

  • Login already hashed in a worker thread. Registration, admin create, bulk invite (up to 100 accounts), forgot-password and reset-password still ran fastapi-users' synchronous hash/verify on the event loop.
  • A mixin (users.core.password_hashing) overrides create, _update and reset_password to offload only the hash/verify calls, using one shared PASSWORD_HELPER.
  • The following are unchanged, checked against upstream fastapi-users:
    • password policy validation;
    • reset fingerprints;
    • atomic credential revocation;
    • privileged-field stripping for unsafe creates;
    • hook order;
    • the dummy-hash timing mitigation;
    • bcrypt→argon2 rehash.
  • Measured with real hashing cost (SM_TEST_REAL_PASSWORD_HASHING=1; details in docs/perf/2026-11-05-users.md):
    • worst event-loop stall for 100 invites: 254 ms → 5 ms;
    • worst event-loop stall for forgot-password: 237 ms → 4 ms.

Admin users page

  • The state counts and role summary shown on every /admin/users/ page, including on each pagination click, are cached per worker for 30 s.
  • The writing worker drops its entry when a change to a counted column (is_active, is_verified, invited_at), a role or a role membership commits. Logins, lockout counters, password rehashes and session revocations do not drop it.
  • The admin service's write methods publish users.admin_summary after commit so other workers refresh: create (including role-less create), delete, invite, disable, enable, mark verified and set roles. The TTL is the floor.
  • Role options are projected, and list items are built from typed columns without re-validation.

Fixed: on_commit callbacks queued before a fastapi-users adapter commit (db_adapter) used to be discarded by request finalization. They now run after that commit.

Pipeline:

  • /optimize replaced listener-based write inference with the repo's local commit-eviction pattern (as in file_storage.aggregates) plus explicit publishes (as in permissions and feature_flags), about 80 fewer lines.
  • Review rounds fixed three things:
    • a role-less create missed the cross-worker publish;
    • login bookkeeping no longer evicts;
    • docs placement.

Local CI: make lint ✓ · make test-py (8 workers) 7915 passed ✓ · make test-js ✓.

https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Deploying simple-module-python with  Cloudflare Pages  Cloudflare Pages

Latest commit: c241f3c
Status: ✅  Deploy successful!
Preview URL: https://a26540bb.simple-module-python.pages.dev
Branch Preview URL: https://fix-s15-perf-users.simple-module-python.pages.dev

View logs

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
🔒 Security Review ✅ Completed 2026-11-05T18:44:36.408576Z 651432f PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@antosubash
antosubash merged commit 3e2c905 into main Nov 5, 2026
17 checks passed
@antosubash
antosubash deleted the fix/s15-perf-users branch November 5, 2026 22:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant