Add per-user rate limit to internal events tracking API

What does this MR do and why?

POST /usage_data/track_events accepts up to 50 events per request, and every accepted event issues several Redis counter writes. This MR caps accepted events at 200 per user per minute, charging the rate limiter one unit per event rather than per request, so batch size does not change the effective budget. Throttled requests receive 429 Too Many Requests with a Retry-After header.

The check sits behind the rate_limit_track_internal_events feature flag, disabled by default.

References

Screenshots or screen recordings

Not applicable: backend only.

How to set up and validate locally

  1. In the Rails console, enable the feature flag:

    Feature.enable(:rate_limit_track_internal_events)
  2. Create a personal access token with the api scope.

  3. Send five 50-event batches:

    for i in $(seq 5); do
      curl --silent --output /dev/null --write-out "%{http_code}\n" \
        --header "PRIVATE-TOKEN: <token>" --header "Content-Type: application/json" \
        --request POST \
        --data "{\"events\": [$(for j in $(seq 50); do printf '{"event":"web_ide_viewed"},'; done | sed 's/,$//')]}" \
        "http://gdk.test:3000/api/v4/usage_data/track_events"
    done
  4. The first four requests return 200; the fifth returns 429.

  5. Disable the flag and repeat: all five return 200.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Related to https://gitlab.com/gitlab-org/gitlab/-/work_items/635568

Edited by Michał Wielich

Merge request reports

Loading
Loading