Use Adaptive Concurrency Control to Prevent Service Collapses with LaunchDarkly
Published August 24, 2026
Fixed server limits usually break during incidents like traffic spikes, causing services to collapse. In this example, we’ll build a Go service that automatically adjusts concurrency limits, using LaunchDarkly to tune the system in real time without redeploying code.
Understand Adaptive Concurrency Control
Adaptive concurrency control is a dynamic traffic management system that continuously measures latency to adjust concurrency limits in real time. Instead of aiming for pure throughput, it optimizes for goodput: the rate of requests completed successfully within acceptable latency limits.
It is useful for:
- Preventing service collapses and thread exhaustion during unexpected traffic spikes or thundering herds
- Protecting downstream databases and third-party APIs from cascading failures when latency surges
- Shedding excess load automatically without relying on fixed static capacity caps or causing additional disruption
If the server can handle more load, limit will increase. If not, limit decreases. Goal is to automatically find the optimal limit.
When Adaptive Limits Are Critical
This is essential for high throughput microservices, streaming connections, and systems prone to thundering herds, fleet resizings, or downstream dependency slowdowns where static capacity caps fail.
Why Static Caps Break
Static concurrency limits require manual tuning and assume stable execution times. An example is when a database or API slows down, requests will consume concurrency slots longer. With static caps, incoming traffic fills queues fast, which causes timeouts, and goodput decreases.
So why not just have a huge static cap? This leads to system failure due to computer restraints like full memory, CPU, huge latency, etc.
What LaunchDarkly Adds
Using an adaptive concurrency algorithm with LaunchDarkly lets you:
- Instantly toggle between legacy static limiting and adaptive limiting using a boolean feature flag (acting as a safety switch)
- Remotely adjust target latency thresholds and adjustment step sizes without redeploying code
- Use rollouts and A/B tests to measure load shedding in production
Prerequisites
Before starting the tutorial, make sure you have the following installed:
- Go 1.21 or higher
- A LaunchDarkly account (free tier works)
- Basic familiarity with concurrency, Go, and HTTP middleware
Build the Baseline Go HTTP Service
First, build a HTTP server protected by a static token based limiter.
Run the following commands to initialize a new Go module:
Create a file named main.go with the following content:
Why This Fails Under Load
In this baseline, the static capacity is fixed. When latency jumps from 50ms to 500ms under load for example, each request holds its token 10 times longer. Incoming requests saturate the service with this low cap, so latency becomes huge and the system cannot adjust.
Implement the Adaptive Concurrency Limiter
Next, implement an adaptive controller that dynamically adjusts capacity based on latency.
Create a file named adaptive.go with the following content:
Add a LaunchDarkly SDK to the Go Application
To safely roll out and tune this adaptive algorithm in production, install the LaunchDarkly Go Server-Side SDK.
Install godotenv to safely load API keys:
Then, update main.go with the following content to integrate LaunchDarkly:
Configure LaunchDarkly Feature Flags
Next, configure the feature flags in the LaunchDarkly UI to control the adaptive algorithm remotely.


1. Create the Safety Switch Flag (enable-adaptive-concurrency)
- Flag name: Enable Adaptive Concurrency
- Flag key:
enable-adaptive-concurrency - Flag type: Boolean
- Default Variations:
true= On,false= Off.
This flag acts as your instant safety kill switch. If the adaptive algorithm acts unexpectedly, flipping this flag back to false instantly drops the service back to static concurrency behavior without requiring a code redeployment or container restart.
2. Create the Tuning Flag (adaptive-limiter-params)
- Flag name: Adaptive Limiter Parameters
- Flag key:
adaptive-limiter-params - Flag type: JSON
- Default Variation Value:
With this JSON flag, operators can adjust latency targets and step size during live traffic spikes directly from the LaunchDarkly console.
Prevent collapses with real-time tuning
Adaptive concurrency control and LaunchDarkly feature flags help prevent cascading failures during real-world latency spikes.
The Real-World Scenario
Consider an outage scenario: a central relational database experiences lock contention, which increases single-query latencies up from 10ms to 400ms. In basic architecture, worker threads will block waiting on open connections. HTTP calls continue to queue which leads to thread exhaustion cascading Out of Memory crashes, and service collapse.
How Adaptive Concurrency Prevents Outages
- Dynamic Capacity Reduction: As downstream response time exceeds
target_latency_ms(for example, 100ms), the adaptive algorithm dynamically steps downcurrentCaptowardmin_capacity. - Immediate Load Shedding: Excess inbound requests receive an immediate 503 Service Unavailable status rather than waiting indefinitely, keeping system worker pools responsive.
- P99 Latency Control: Tail latency stays bounded near your specified target because request queue depths are kept minimal.
- Live Algorithm Tuning: If 100ms is too conservative during a high-traffic event, update the LaunchDarkly JSON flag
target_latency_msto 200ms. The application instantly reads the updated threshold without needing a binary release.
Create a .env file in the root directory of your project:
Add .env to your .gitignore.
Run the server:
Toggle the enable-adaptive-concurrency feature flag on and off in your LaunchDarkly console while simulating HTTP calls to watch the service switch dynamically between static limiting and adaptive load shedding.
Next Steps for Adaptive Concurrency Control
By combining Go’s concurrency features with LaunchDarkly feature flags, you can build a dynamic load-shedding architecture that automatically finds the optimal concurrency limit to prevent cascading outages while remaining fully controllable in real time.
To expand on this foundation, consider exploring:
- Looking at different adaptive algorithms (for example, Additive Increase Multiplicative Decrease (AIMD), gradient, and others).
- Integrating LaunchDarkly target rules to apply different adaptive thresholds to free vs. enterprise API tier users.
- Hooking adaptive token capacity metrics directly into Prometheus or Datadog dashboards for real-time observability.
If you have questions about this or want to share how you manage concurrency control in your work, connect with me on LinkedIn.