Skip to content

Conversation

@1-23-smy
Copy link

  • Backend: Add ScopedRateThrottle to IdentityViewSet (30 req/min)
  • Frontend: Increase debounce from 500ms to 750ms
  • Config: Add IDENTITY_SEARCH_THROTTLE_RATE env variable
  • Tests: Add test for identity search throttling

This fixes aggressive API requests when searching for identities.


Thanks for submitting a PR! Please check the boxes below:

  • I have added information to docs/ if required so people know about the feature
  • I have filled in the Changes section below
  • I have filled in the How did you test this code section below
  • I have used a Conventional Commit title for this Pull Request

Changes

Backend Changes

  • api/environments/identities/views.py
    Added ScopedRateThrottle to IdentityViewSet with scope identity_search

  • api/app/settings/common.py
    Added configurable IDENTITY_SEARCH_THROTTLE_RATE environment variable (default: 30/min)

Frontend Changes

  • frontend/common/useDebouncedSearch.ts
    Increased debounce time from 500ms to 750ms to reduce request frequency during typing

Configuration

The rate limit can be customized via environment variable:

IDENTITY_SEARCH_THROTTLE_RATE="30/min"  # default

How did you test this code?

Unit Tests

  • Added test_identity_search_is_throttled in
    api/tests/unit/environments/identities/test_unit_identities_views.py

Manual Testing

  1. Built a local Docker image with the changes
  2. Made 35 rapid requests to the identity search endpoint:
for i in {1..35}; do
  curl -s -o /dev/null -w "Request $i: %{http_code}\n" \
    -H "Authorization: Token $TOKEN" \
    "http://localhost:8009/api/v1/environments/$ENV_KEY/identities/?q=test"
done
  1. Verified that requests after the 30/min threshold return 429 Too Many Requests:
Request 33: 200
Request 34: 429  ← Rate limit triggered
Request 35: 429

- Backend: Add ScopedRateThrottle to IdentityViewSet (30 req/min)
- Frontend: Increase debounce from 500ms to 750ms
- Config: Add IDENTITY_SEARCH_THROTTLE_RATE env variable
- Tests: Add test for identity search throttling

Fixes aggressive API requests when searching for identities.
Copilot AI review requested due to automatic review settings December 22, 2025 07:20
@1-23-smy 1-23-smy requested review from a team as code owners December 22, 2025 07:20
@1-23-smy 1-23-smy requested review from khvn26 and talissoncosta and removed request for a team December 22, 2025 07:20
@vercel
Copy link

vercel bot commented Dec 22, 2025

@smy-637q is attempting to deploy a commit to the Flagsmith Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions bot added front-end Issue related to the React Front End Dashboard api Issue related to the REST API labels Dec 22, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds rate limiting to the identity search endpoint to prevent aggressive API requests. It includes backend throttling via Django REST Framework's ScopedRateThrottle, a configurable environment variable for the rate limit, frontend debounce increase, and a test to verify throttling behavior.

  • Backend throttling implementation with ScopedRateThrottle at 30 requests/minute
  • Frontend debounce increase from 500ms to 750ms across all search components
  • Configurable rate limit via IDENTITY_SEARCH_THROTTLE_RATE environment variable

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
api/environments/identities/views.py Adds ScopedRateThrottle with identity_search scope to IdentityViewSet
api/app/settings/common.py Adds IDENTITY_SEARCH_THROTTLE_RATE environment variable configuration (default: 30/min)
api/tests/unit/environments/identities/test_unit_identities_views.py Adds test to verify identity search throttling behavior
frontend/common/useDebouncedSearch.ts Increases debounce time from 500ms to 750ms for all search operations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

def test_identity_search_is_throttled(
admin_client: APIClient,
environment: Environment,
settings,
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The test is missing the reset_cache fixture parameter which is used in other throttle tests to ensure proper cache cleanup between tests. DRF's ScopedRateThrottle uses Django's cache backend to track request counts, and without cache clearing, throttle state could persist between tests causing flaky test failures.

Add reset_cache to the function parameters (see examples in api/tests/integration/custom_auth/end_to_end/test_custom_auth_integration.py lines 486-491 and 527-533).

Suggested change
settings,
settings,
reset_cache,

Copilot uses AI. Check for mistakes.
Comment on lines +7 to +10
const [debounceTime, setDebounceTime] = useState(750)

useEffect(() => {
setDebounceTime(searchInput.length < 1 ? 0 : 500)
setDebounceTime(searchInput.length < 1 ? 0 : 750)
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

Increasing the debounce time from 500ms to 750ms will affect all components using useDebouncedSearch, not just identity search. This includes:

  • AuditLog.tsx
  • ConversionEventSelect.tsx
  • CreateSegment.tsx (segment search)
  • SegmentsPage.tsx
  • SplitTestPage.tsx
  • UserPage.tsx
  • UsersPage.tsx (identity search)
  • TableValueFilter.tsx

While this may be acceptable to reduce API calls globally, consider whether a 250ms increase is appropriate for all these use cases. If the intent is to only throttle identity search, consider creating a separate hook like useDebouncedIdentitySearch with the higher debounce time, or make the debounce time configurable via a parameter.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Choose a reason for hiding this comment

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

@Zaimwa9 are you able to chime in here - do you think this is something we need to be concerned about?

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

This PR is being reviewed by Cursor Bugbot

Details

Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

smy-637q and others added 2 commits December 22, 2025 13:04
- Use get_throttles() method to conditionally apply throttle only to 'list' action
- Update test to use mocker.patch and reset_cache fixture for proper cleanup
- Follow existing patterns from FFAdminUserViewSet and OrganisationViewSet
@vercel
Copy link

vercel bot commented Dec 31, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
docs Ready Ready Preview, Comment Dec 31, 2025 11:09am
2 Skipped Deployments
Project Deployment Review Updated (UTC)
flagsmith-frontend-preview Ignored Ignored Preview Dec 31, 2025 11:09am
flagsmith-frontend-staging Ignored Ignored Preview Dec 31, 2025 11:09am

@matthewelwell
Copy link
Contributor

@1-23-smy could you check the unit test failures here please?

@1-23-smy
Copy link
Author

1-23-smy commented Dec 31, 2025

matthewelwell Sure, I will look into it

smy-637q and others added 2 commits December 31, 2025 16:49
The test.py settings file overrides DEFAULT_THROTTLE_RATES from common.py,
so identity_search scope was missing in the test environment.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api Issue related to the REST API front-end Issue related to the React Front End Dashboard

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants