Skip to content

feat(llm-analytics): dedicated rate limit for prompt fetch endpoints - #108384

Merged
trunk-io[bot] merged 1 commit into
masterfrom
prompts/prompt-fetch-rate-limit
Sep 29, 2026
Merged

trunk-io[bot] merged 1 commit into
masterfrom
prompts/prompt-fetch-rate-limit

Conversation

@jurajmajerik

Copy link
Copy Markdown
Contributor

Problem

SDK clients that poll prompts on a fixed interval hit the shared API budget's sustained cap (4,800/hour) and get 429s, even after batching every poll into one get_all() request. A fleet polling every 5 minutes reaches the cap at around 400 processes. Internal metrics show several teams' prompt fetches rejected by this cap over the last 30 days.

Feature flags solved the same problem for remote_config with a dedicated per-minute throttle.

Changes

  • Prompt fetch endpoints (list, get-by-name, resolve-by-name) now draw on a dedicated budget of 600/minute per personal API key, with no hourly cap.
  • Prompt polling no longer competes with the key's other API calls, which keep the standard 480/minute + 4,800/hour budget.
  • Publishing (update_by_name) keeps its existing stricter throttles.

Design rationale: the limit is per-minute only because polling is steady, not bursty; an hourly cap is what rejects a fleet that polls on an interval. This copies the feature_flag_remote_config throttle shape. A prompt fetch is a cheap indexed Postgres read that the SDK caches for 300 seconds, so the endpoint does not need the general API budget's protection.

Nothing user-visible changes except fewer 429s for SDK prompt polling.

How did you test this code?

Extended the existing get_throttles tests in test_llm_prompt.py: one parameterized test over the three fetch actions asserts each uses exactly the dedicated throttle. It catches a regression that routes prompt fetches back onto the shared budget, which silently reintroduces the hourly cap.

Not tested: an end-to-end 429 at the 601st request in a minute. The counting is DRF SimpleRateThrottle behavior already exercised by the framework and by existing throttles.

Automatic notifications

  • Publish to changelog?

Docs update

The public rate limiting docs live in posthog.com; a follow-up PR there will document the dedicated prompt fetch limit.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Agent: Claude Code, Fable 5 (claude-fable-5)

Skills invoked: /wt, /improving-drf-endpoints, /writing-tests, /writing-code-comments, /reviewing-with-coderabbit, /writing-pr-descriptions.

CodeRabbit CLI: signed out; the user chose to skip the local pass, so the PR opened without one.

Duplicate search found no open PR touching prompt fetch rate limiting. The limit was sized against production request metrics for the prompt fetch views reviewed during the session. The work originates from customer feedback about prompt polling 429s; no customer material appears in the diff or this description.

@jurajmajerik jurajmajerik self-assigned this Sep 29, 2026
@trunk-io

trunk-io Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

😎 Merged successfully - details.

@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

🤖 CI report

⚠️ Trunk lane — backend Python lane

This PR is assigned to the backend Python lane. It runs backend Python tests and may merge in parallel with PRs in other lanes.

⚠️ Duplication (Python) — 1 new duplicated block (worst 78 tokens)

New Python code duplication introduced by this branch. Fails at 70+ tokens in app code, or 150+ tokens when both copies live in test files. Advisory while the gate proves itself: extract a shared helper instead of copying.

First copy Second copy Lines Tokens
posthog/api/llm_prompt.py:120 products/skills/backend/api/skills.py:591 13 78
✅ Duplication (TypeScript) — clean

New TypeScript code duplication introduced by this branch. Fails at 70+ tokens in app code, or 150+ tokens when both copies live in test files. Advisory while the gate proves itself: extract a shared helper instead of copying.

✅ Playwright — all passed

All tests passed.

View test results →

@greptile-apps

greptile-apps Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Retrigger

[Medium risk]

The PR appears safe to merge, with a non-blocking concern about sustained use of expensive list queries.

Reviews (1) · Last reviewed commit: "feat(llm-analytics): dedicated rate limi..."

Comment thread posthog/api/llm_prompt.py Resolved
@jurajmajerik
jurajmajerik marked this pull request as ready for review September 29, 2026 14:21
@pr-assigner-resolver-posthog
pr-assigner-resolver-posthog Bot requested a review from a team September 29, 2026 14:22
@coderabbitai

coderabbitai Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: PostHog/posthog/.coderabbit.yaml

Review profile: QUIET

Plan: Enterprise

Run ID: 6311e6c5-5dac-418a-8ca5-bce4afbe21d2

📥 Commits

Reviewing files that changed from the base of the PR and between 8bd1d39 and 7040b9a.

📒 Files selected for processing (3)
  • posthog/api/llm_prompt.py
  • posthog/api/test/test_llm_prompt.py
  • posthog/rate_limit.py

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 10 remain after this review.


📝 Walkthrough

Walkthrough

The list, get_by_name, and resolve_by_name actions now use LLMPromptFetchRateThrottle, which has a dedicated llm_prompt_fetch scope and a limit of 600 requests per minute. A parameterized test checks that each action uses only this throttle.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to 7040b

Prompt fetches now have a dedicated per-key 600-per-minute limit, with publishing and other API throttle behavior unchanged. No material merge-blocking risk was found; proceed with normal checks.

Security Architecture Review

Security architecture risk: 🟡 Moderate · up to 7040b

Prompt reads gain a higher sustained allowance. Access remains tied to existing credentials and project permissions, but the higher allowance could increase backend load, particularly for searches and resolved lists.

Retained concerns

  • Medium · security · inferred: A valid personal API key can now sustain up to 600 prompt fetches per minute without the former shared hourly cap. List requests can include prompt-text search and reference resolution, making increased backend load plausible rather than establishing that all fetches are cheap indexed reads.
Security review details

Security Blast Radius

  • inferred — Exposure is concentrated in prompt-read traffic from holders of valid personal API keys and the backend serving those reads. The 600/minute budget is per key, not a demonstrated project-wide ceiling.

Security Findings and Attack Paths

  • inferred — A credentialed caller can use the increased sustained allowance for list searches or resolved lists. The source supports a potential availability impact, not a verified outage or unauthorized prompt access.

Trust Boundaries and Controls

  • observed — Personal-key authentication validates a key before recording its hash; throttling prefers that validated hash. The view retains project-access permission checks and team-scoped prompt selection.

Resilience and Maintainability Implications

  • observed — Cache-path exceptions fail open under the inherited throttle policy. The available source delegates counting to the framework, so concurrent counting and recovery behavior remain unverified.

Hardening Proposals

  • proposed — Validate sustained load for search and reference-resolution requests under the new allowance, and check limit enforcement during concurrent requests and cache recovery.
🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The description clearly explains the problem, user impact, changes, testing scope, documentation follow-up, and agent context. The required Release status selection is missing, but the description is …
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Comment @coderabbitai help to get the list of available commands.

@jurajmajerik jurajmajerik added the stamphog Request AI approval (no full review) label Sep 29, 2026
@jurajmajerik
jurajmajerik removed the request for review from a team September 29, 2026 14:27

@stamphog stamphog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Approved.

Contained, reversible throttle change on read-only prompt fetch endpoints. It uses the same base class as the throttles it replaces, is covered by a parameterized test, and the author is on the owning team.

  • Author wrote 0% of the modified lines and has 52 merged PRs in these paths (familiarity MODERATE).
  • 👍 on the PR from greptile-apps[bot].
Gate mechanics and policy version
Gate Result
prerequisites ✓ all clear
deny-list ✓ no deny categories matched
size ✓ 22L, 2F substantive, 39L/3F incl. docs/generated/snapshots — within ceiling
tier ✓ T1-agent / T1b-small (39L, 3F, single-area, feat)
stamphog 2.3.0 .stamphog/policy.yml @ 7040b9a · reviewed head 7040b9a

@trunk-io

trunk-io Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Static Badge   Static Badge   Static Badge

View Full Report ↗︎ ⋅ Docs

@trunk-io
trunk-io Bot merged commit f7d967c into master Sep 29, 2026
406 of 425 checks passed
@trunk-io
trunk-io Bot deleted the prompts/prompt-fetch-rate-limit branch September 29, 2026 15:24
@deployment-status-posthog

deployment-status-posthog Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-09-29 16:02 UTC Run
prod-us ✅ Deployed 2026-09-29 16:16 UTC Run
prod-eu ✅ Deployed 2026-09-29 16:23 UTC Run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stamphog Request AI approval (no full review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant