Skip to content

Frontend treats 429 from the per-user concurrency limiter as a hard failure #338

Closed

Description

@dpb97

Summary

The per-user concurrency limiter (internal/middleware/user_concurrency.go, default MAX_USER_CONCURRENCY=16) rejects request bursts with 429 Too Many Requests and Retry-After: 1. The API client (frontend/src/lib/api/core.js) does not retry these, so views that fan out many reads at once fail intermittently even though the server explicitly asks the client to retry a second later.

Where it shows up

  • Collection boards (/collections/{id}/board): many cards trigger parallel reads (e.g. MilestoneCombobox), plus workspaceDataStore.initializeGlobal(). Console:
    WorkspaceDataStore: global initialization failed Error: Too many concurrent requests
    Failed to load milestones: Error: Too many concurrent requests
    
  • Item detail opened from a collection board: since f9752b0 the fallback path hydrates six reference lists with Promise.all. If any one of them gets a 429, the whole modal shows "Too many concurrent requests" instead of the item.
  • It gets much more frequent with a slower database (longer in-flight requests) – we hit it constantly on a small Azure PostgreSQL Flexible Server (B1ms) and still occasionally on B2s.

Expected

Safe requests rejected by the limiter are retried after Retry-After, so a short burst degrades to a small delay instead of an error.

Environment

main @ 5832187 (also v0.8.9), Docker image, PostgreSQL 16 (Azure Flexible Server), single replica, default MAX_USER_CONCURRENCY.

I have a small PR ready that adds a bounded retry for GET/HEAD/OPTIONS in core.js.

Activity

  1. stefan-ernst commented on Oct 14, 2026

    @stefan-ernst
    Contributor

    Hey, thank you for the report and the PR.

    There are a few things to address:

    • The max concurrency is deliberately low to identify these fan-outs and fix / optimize them. I will have a look at the milestonecombobox reads
    • I am checking the entire request tree for board / list / etc to find more optimizations. The goal would be to stay within the request budget at all times, even with custom card fields etc
    • The db connection latency would be interesting to see - can you screenshot Admin -> Diagnostics -> Infrastructure -> Database pools?
    Image

    The retry-after fix is still valuable to avoid hard failures as you described, I will pull this in.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions