Skip to content

feat: add Redis-backed SMTP rate limiting, email caching, and provide…#51

Draft
revanth127 wants to merge 1 commit into
sharmavaibhav31:mainfrom
revanth127:feat/smtp-rate-limiting
Draft

feat: add Redis-backed SMTP rate limiting, email caching, and provide…#51
revanth127 wants to merge 1 commit into
sharmavaibhav31:mainfrom
revanth127:feat/smtp-rate-limiting

Conversation

@revanth127
Copy link
Copy Markdown

@revanth127 revanth127 commented May 17, 2026

closes #12

  • Migrate rate limiting from in-memory to Redis (atomic INCR + EXPIRE)
  • Add per-domain rate limit: 3 verification attempts per hour
  • Implement Redis-backed result cache with 24h TTL
  • Skip caching transient 'unverified' states (network failures)
  • Add SMTP blocklist for known providers (Gmail, Outlook, Yahoo, iCloud, etc.)
  • Allow blocklist extension via VERIFIER_SMTP_BLOCKLIST_EXTENDS env var
  • Graceful degradation when Redis is unavailable (fail open, log warnings)
  • Works across multiple workers/processes

@vercel
Copy link
Copy Markdown

vercel Bot commented May 17, 2026

@revanth127 is attempting to deploy a commit to the Vaibhav Sharma's projects Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Copy Markdown
Owner

@sharmavaibhav31 sharmavaibhav31 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR — the Redis-backed direction is good overall, especially the move away from process-local rate limiting.

However, while reviewing verifier.py, I found several structural and correctness issues that need cleanup before merge:

  • _resolve_mx() currently appears malformed/mixed with verification flow logic
  • email is referenced inside _resolve_mx() without being defined in scope
  • rate-limit rollback using DECR after limit exceed is race-prone under concurrency
  • Redis/cache concerns and SMTP verification flow are too tightly coupled right now
  • some fallback/error-handling paths need hardening
  • input normalization/sanitization for cache + rate-limit keys should be stricter
  • async execution/timeouts around SMTP verification need another pass
  • there are a few maintainability concerns where large sections feel over-abstracted compared to the current codebase style

Please do a focused cleanup/refactor pass on verifier.py before further review.

Priority should be:

  1. correctness
  2. concurrency safety
  3. Redis failure handling
  4. clean separation of responsibilities
  5. consistency with existing project architecture/style

Also please test:

  • Redis unavailable scenarios
  • concurrent verification attempts
  • cache hit/miss behavior
  • rate-limit expiration/reset behavior
  • malformed email input handling

Once those are cleaned up, I’ll continue with a deeper review.

Comment thread .gitignore
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine, this works.

@revanth127
Copy link
Copy Markdown
Author

revanth127 commented May 20, 2026

Thanks for the PR — the Redis-backed direction is good overall, especially the move away from process-local rate limiting.

However, while reviewing verifier.py, I found several structural and correctness issues that need cleanup before merge:

  • _resolve_mx() currently appears malformed/mixed with verification flow logic
  • email is referenced inside _resolve_mx() without being defined in scope
  • rate-limit rollback using DECR after limit exceed is race-prone under concurrency
  • Redis/cache concerns and SMTP verification flow are too tightly coupled right now
  • some fallback/error-handling paths need hardening
  • input normalization/sanitization for cache + rate-limit keys should be stricter
  • async execution/timeouts around SMTP verification need another pass
  • there are a few maintainability concerns where large sections feel over-abstracted compared to the current codebase style

Please do a focused cleanup/refactor pass on verifier.py before further review.

Priority should be:

  1. correctness
  2. concurrency safety
  3. Redis failure handling
  4. clean separation of responsibilities
  5. consistency with existing project architecture/style

Also please test:

  • Redis unavailable scenarios
  • concurrent verification attempts
  • cache hit/miss behavior
  • rate-limit expiration/reset behavior
  • malformed email input handling

Once those are cleaned up, I’ll continue with a deeper review.

Thanks for the PR — the Redis-backed direction is good overall, especially the move away from process-local rate limiting.

However, while reviewing verifier.py, I found several structural and correctness issues that need cleanup before merge:

  • _resolve_mx() currently appears malformed/mixed with verification flow logic
  • email is referenced inside _resolve_mx() without being defined in scope
  • rate-limit rollback using DECR after limit exceed is race-prone under concurrency
  • Redis/cache concerns and SMTP verification flow are too tightly coupled right now
  • some fallback/error-handling paths need hardening
  • input normalization/sanitization for cache + rate-limit keys should be stricter
  • async execution/timeouts around SMTP verification need another pass
  • there are a few maintainability concerns where large sections feel over-abstracted compared to the current codebase style

Please do a focused cleanup/refactor pass on verifier.py before further review.

Priority should be:

  1. correctness
  2. concurrency safety
  3. Redis failure handling
  4. clean separation of responsibilities
  5. consistency with existing project architecture/style

Also please test:

  • Redis unavailable scenarios
  • concurrent verification attempts
  • cache hit/miss behavior
  • rate-limit expiration/reset behavior
  • malformed email input handling

Once those are cleaned up, I’ll continue with a deeper review.

Thanks for the detailed review. I’ll go through the issues you pointed out, research the best approach for the concurrency and Redis handling parts, and do my best to clean up/refactor verifier.py accordingly before the next review.

@revanth127 revanth127 force-pushed the feat/smtp-rate-limiting branch from 5c16767 to b665b09 Compare May 20, 2026 06:58
@revanth127
Copy link
Copy Markdown
Author

Quick update — after spending more time on the verifier refactor and digging deeper into the issues from the review, I realized the async concurrency, Redis coordination, and SMTP reliability parts are currently beyond my experience level to complete confidently to the standard the project needs.

Rather than keep the PR hanging or continue with unreliable changes, I think it’s better for me to step back from this issue for now. I really appreciate the detailed review and guidance though — I learned a lot while attempting it.

Sorry for the inconvenience, and thanks again for the feedback.

@sharmavaibhav31
Copy link
Copy Markdown
Owner

Thanks for the honest update, Revanth. Stepping back was definitely the right call unless you wanted to be personally responsible for Redis exploding and rate limits completely losing their minds across our workers.

On paper, your blueprint was solid:

  • Moving away from process-local limiting was smart.

  • Redis coordination and caching are exactly what we need.

  • Blocklisting providers is a great touch.

However, executing it safely means rewriting the whole thing to survive:

  • Concurrency issues that will absolutely haunt us.
  • Messy Redis interactions and unpredictable async timeouts.
  • Schema and maintainability consistency (gotta keep it clean).

Keeping the PR open for now as a draft/reference, but we aren't merging this into main until it gets a heavy architectural cleanup. Thanks for doing the heavy lifting on the research though!

@sharmavaibhav31 sharmavaibhav31 marked this pull request as draft May 29, 2026 14:19
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.

[Improvement] SMTP verification is too aggressive - getting blocklisted

2 participants