Skip to content

Improve concurrent request limit error messaging and documentation#3842

Open
KyleAMathews wants to merge 6 commits intomainfrom
claude/investigate-cdn-scaling-QZMgQ
Open

Improve concurrent request limit error messaging and documentation#3842
KyleAMathews wants to merge 6 commits intomainfrom
claude/investigate-cdn-scaling-QZMgQ

Conversation

@KyleAMathews
Copy link
Contributor

@KyleAMathews KyleAMathews commented Feb 13, 2026

Improves the 503 error response when Electric's concurrent request limit is exceeded, replacing a generic "overloaded" message with specific, actionable information. Adds documentation for the ELECTRIC_MAX_CONCURRENT_REQUESTS config option and a troubleshooting guide.

Root Cause

When too many clients connect simultaneously and exhaust the admission control permits, Electric returns a 503 with {"code": "overloaded", "message": "Server is currently overloaded, please retry"}. This tells the operator nothing about which limit was hit, what the limit is, or how to fix it — leading to unnecessary debugging.

Approach

Error message improvement: The error code is now "concurrent_request_limit_exceeded" and the message includes the request kind (initial or existing) and the configured limit value. This lets operators immediately understand which pool is saturated and what to change.

Documentation: Added two new sections:

  • Config docs for ELECTRIC_MAX_CONCURRENT_REQUESTS explaining the two-pool model (initial vs existing requests)
  • Troubleshooting guide for the 503 error with three solutions: CDN with request collapsing (recommended), increasing the limit, or reducing concurrent subscriptions

Key invariant: The error message format must match what the documentation shows. Review caught a mismatch from an intermediate commit and corrected it.

Verification

cd packages/sync-service && mix test test/electric/plug/router_test.exs

The test verifies the new error code and that the message includes "Concurrent existing request limit exceeded".

Files changed

  • packages/sync-service/lib/electric/plug/serve_shape_plug.ex — Changed error code and message to include request kind and limit
  • packages/sync-service/test/electric/plug/router_test.exs — Updated assertions for new error format
  • website/docs/api/config.md — Added ELECTRIC_MAX_CONCURRENT_REQUESTS documentation
  • website/docs/guides/troubleshooting.md — Added 503 concurrent request limit troubleshooting section

🤖 Generated with Claude Code

…ntrol limits

Root cause: 200 clients × 13 collections = 2,600 concurrent long-poll connections,
exceeding the default 1,000 existing-request admission control limit. The Vary:
Authorization header in their proxy also defeats CDN request collapsing.

https://claude.ai/code/session_01ASiu2KpoheTmvkpJi1Di7c
- Change error code from "overloaded" to "concurrent_request_limit_exceeded"
  with a message that includes the actual limit, the request kind (initial vs
  existing), and pointers to ELECTRIC_MAX_CONCURRENT_REQUESTS and the
  troubleshooting docs
- Add troubleshooting section for 503 concurrent request limit exceeded
- Document ELECTRIC_MAX_CONCURRENT_REQUESTS and ELECTRIC_LONG_POLL_TIMEOUT
  in the config reference
- Remove investigation file (analysis folded into docs)

https://claude.ai/code/session_01ASiu2KpoheTmvkpJi1Di7c
@netlify
Copy link

netlify bot commented Feb 13, 2026

Deploy Preview for electric-next ready!

Name Link
🔨 Latest commit dc84aa5
🔍 Latest deploy log https://app.netlify.com/projects/electric-next/deploys/6994eab28fac650009db1801
😎 Deploy Preview https://deploy-preview-3842--electric-next.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@codecov
Copy link

codecov bot commented Feb 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.07%. Comparing base (8fe28cc) to head (dc84aa5).
⚠️ Report is 10 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@             Coverage Diff             @@
##             main    #3842       +/-   ##
===========================================
+ Coverage   75.75%   87.07%   +11.32%     
===========================================
  Files          11       25       +14     
  Lines         693     2314     +1621     
  Branches      174      583      +409     
===========================================
+ Hits          525     2015     +1490     
- Misses        167      297      +130     
- Partials        1        2        +1     
Flag Coverage Δ
packages/experimental 87.73% <ø> (ø)
packages/react-hooks 86.48% <ø> (ø)
packages/start 82.83% <ø> (ø)
packages/typescript-client 91.91% <ø> (?)
packages/y-electric 56.05% <ø> (ø)
typescript 87.07% <ø> (+11.32%) ⬆️
unit-tests 87.07% <ø> (+11.32%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@blacksmith-sh

This comment has been minimized.

claude and others added 3 commits February 13, 2026 04:32
The error code and limit value are enough for an engineer to find the
docs. The env var name and URL are noise for end-user clients.

https://claude.ai/code/session_01ASiu2KpoheTmvkpJi1Di7c
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@blacksmith-sh

This comment has been minimized.


When the limit is exceeded, Electric responds with `503` and a `Retry-After` header. See the [troubleshooting guide](/docs/guides/troubleshooting#_503-mdash-concurrent-request-limit-exceeded) for details.

Each `live=true` long-poll request holds a permit for up to 20 seconds, so the effective limit is determined by the number of concurrent shape subscriptions across all connected clients. Putting a [CDN with request collapsing](/docs/api/http#collapsing-live-requests) in front of Electric is the recommended way to handle high connection counts.
Copy link
Member

Choose a reason for hiding this comment

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

long-poll request holds a permit for up to 20 seconds

This phrase is mentioned twice in this PR. "Permit" looks out of place here. The following sounds more natural, IMO

long-poll request holds the connection open for up to 20 seconds.

ELECTRIC_MAX_CONCURRENT_REQUESTS='{"initial": 500, "existing": 3000}'
```

Live long-poll connections are lightweight Erlang processes, so most hardware can handle higher limits. The default of 1,000 is conservative.
Copy link
Member

Choose a reason for hiding this comment

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

Could be a discussion for a different PR but this documentation doesn't explain why the limit is conservative. The rest of the narrative mentions things like "your cpu and mem could be fine" and "live connections are lightweight process". So why artificially limit the concurrency to 1000 then?

I think it should be 10k minimum.

  • Partly because there's no logging on the server side when the limit is reached. The developer will only learn about it being hit if they have proper telemetry/alerting in place in their proxy between clients and Electric.

  • Partly because having a CDN in front doesn't guarantee that Electric will be hit by fewer connections, when request collapsing cannot be applied to to different shape params.

  • And partly because 10k simultaneous connections used to be a challenge, but at this point it should be table stakes even on modest HW.

The term C10k was coined in 1999 by software engineer Dan Kegel, [...] serving 10,000 clients at once over 1 gigabit per second in that year.

As of 2025, the problem has long since been solved, with the number of possible connections to a single computer being in the millions.

https://en.wikipedia.org/wiki/C10k_problem

Address review feedback: increase the default concurrent existing
request limit from 1,000 to 10,000 and replace "holds a permit"
with "holds the connection open" in user-facing docs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@KyleAMathews
Copy link
Contributor Author

@alco suggestions applied!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Comments