Skip to content

⚡ Bolt: Offload bcrypt to threadpool to prevent event loop blocking - #93

Open
benpiper wants to merge 1 commit into
mainfrom
bolt-bcrypt-threadpool-6929092177359738763
Open

⚡ Bolt: Offload bcrypt to threadpool to prevent event loop blocking#93
benpiper wants to merge 1 commit into
mainfrom
bolt-bcrypt-threadpool-6929092177359738763

Conversation

@benpiper

@benpiper benpiper commented Jul 1, 2026

Copy link
Copy Markdown
Owner

💡 What

Refactored get_password_hash and verify_password in backend/auth.py to be async functions that offload the slow, CPU-bound bcrypt hashing algorithms to a background threadpool using starlette.concurrency.run_in_threadpool. The /api/auth/register, /api/auth/login, and /api/auth/setup endpoints in backend/main.py were updated to await these new async functions.

🎯 Why

Password hashing algorithms like bcrypt are intentionally designed to be slow and CPU-intensive to thwart brute-force attacks (typically taking 100ms - 500ms). When called synchronously inside an async def FastAPI endpoint, these operations completely block the underlying Python asyncio event loop. This means that while one user is logging in, no other concurrent requests (like serving video segments, polling jobs, etc.) can be processed by the server, causing severe and cascading latency spikes across the entire application.

📊 Impact

  • Event Loop Non-Blocking: Concurrent requests are no longer blocked while authentication routes hash or verify passwords.
  • Scalability: The server can now handle multiple simultaneous login/registration requests efficiently without locking up the main thread.
  • Performance: Overall API latency variance and stuttering during high-load authentication events will be eliminated.

🔬 Measurement

To verify the improvement:

  1. Run the FastAPI backend locally: cd backend && uv run uvicorn main:app --port 8000.
  2. Use a load testing tool (like wrk or locust) or run concurrent curl requests hitting a lightweight, non-blocking endpoint (e.g., /api/auth/status or /api/features).
  3. Simultaneously send a request to /api/auth/login with valid or invalid credentials.
  4. Before Optimization: The lightweight requests will stall and wait for the login request's bcrypt hash to complete before returning.
  5. After Optimization: The lightweight requests will return immediately (in milliseconds), even while the login request is actively computing the bcrypt hash in the background threadpool.

PR created automatically by Jules for task 6929092177359738763 started by @benpiper

- Re-defined `verify_password` and `get_password_hash` as async in `auth.py`.
- Offloaded internal `bcrypt` calls to `starlette.concurrency.run_in_threadpool`.
- Updated endpoints in `main.py` (`login`, `register`, `setup_initial_admin`) to await these functions.
- Prevents CPU-bound bcrypt hashing from blocking the asyncio event loop and causing severe latency spikes for concurrent API requests.

Co-authored-by: benpiper <4343814+benpiper@users.noreply.github.com>
@google-labs-jules

Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

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