When an application enforces per-user message quotas or subscription-tier rate limits but shows no indicator, users experience silent, opaque walls — a request goes out, nothing comes back, and there is no signal explaining why. This erodes trust and generates support tickets that cost real time. The iso-25010:2011 performance-efficiency dimension treats predictability as a quality attribute: users cannot manage their own consumption if the system conceals it. Cost-efficiency also degrades on the operator side when users retry aggressively against an invisible limit, amplifying API spend without delivering additional value.
Informational because the failure harms user experience and increases support load but does not expose data or create a security vulnerability.
Return remaining quota from your API route and render it near the input in src/components/chat/ChatInput.tsx. Only render the indicator when a limit is actually enforced — do not show it for unlimited tiers.
{usageLimit && (
<span className={cn(
"text-xs",
remaining < 5 ? "text-destructive" : "text-muted-foreground"
)}>
{remaining} / {usageLimit} messages remaining
</span>
)}
Emit X-RateLimit-Remaining (or equivalent) as a response header in app/api/chat/route.ts so the client can read it without parsing the full response body.
ID: ai-chat-visibility.loading-and-streaming.token-usage-indicator
Severity: info
What to look for: Count all usage-limiting mechanisms in the codebase: rate limiting middleware, per-user quotas, subscription tier checks on the chat route. Check whether any form of usage information is displayed near the chat input or in the interface header. This could be a message count ("5 / 20 messages remaining"), a token counter, or a context window indicator. Look for usage tracking in API response handling and UI rendering.
Pass criteria: The interface shows some form of usage or limit indicator when the application has at least 1 usage limit. For unlimited applications, this check passes by default. Report even on pass: "Found N usage limit mechanisms; indicator displays [description]."
Fail criteria: The application has usage limits (rate limiting, per-user message quotas, or subscription tier limits) but displays no indicator — users hit limits without warning.
Skip (N/A) when: The application has no usage limits (no rate limiting, no per-user quotas, no subscription gating on chat usage). Signal: no rate limiting middleware, no usage tracking in the database, and no subscription-based access control on the chat route.
Detail on fail: "Chat has per-user message limits enforced in API route but no usage indicator in UI — users hit limits without warning"
Remediation: In your API route at app/api/chat/route.ts, return usage data as a header or in the response body. In src/components/chat/ChatInput.tsx, render the indicator:
{usageLimit && (
<span className={cn("text-xs", remaining < 5 ? "text-destructive" : "text-muted-foreground")}>
{remaining} / {usageLimit} messages remaining
</span>
)}