Outbound HTTP calls are made by the majority of ASP.NET Core apps. They could make calls to third-party platforms, cloud services, internal microservices, payment services, and authentication APIs.
HttpClient often has a lengthy lifespan and depends on connection pooling for these applications. Reusing connections is a crucial component of effective HTTP communication as it eliminates the expense of creating a new TCP connection for each request.
However, enduring relationships create a new issue.
When a service behind a hostname modifies its IP address, what happens?
This can happen during:
- Deployment
- Failover
- DNS-based load balancing
- Infrastructure migration
- Disaster recovery
- Service scaling
If an application keeps using an existing connection for too long, changing DNS information does not necessarily mean that an already-established connection immediately moves to the new destination.
.NET 11 introduces configurable HTTP connection eviction capabilities that provide developers with more control over when pooled connections should be removed.
This article explains the problem, shows how to configure connection lifetime behavior, and demonstrates how to test DNS failover without claiming that a particular configuration is universally optimal.
Why DNS Changes Do Not Automatically Move Existing Connections
Consider an API client calling:
Initially, DNS resolves the hostname to:
Later, the service moves:
A new DNS lookup can discover the new address.
However, an application may already have an established HTTP connection to the previous destination.
Conceptually:
The existing connection does not become a connection to the new IP simply because DNS changed.
That is where connection lifetime management becomes important.
How HttpClient Connection Pooling Works
A common pattern is to reuse a single HttpClient rather than creating a new instance for every request.
For example:
The underlying HTTP handler maintains connections and can reuse them for subsequent requests.
This is generally preferable to repeatedly doing:
Creating clients repeatedly can prevent effective connection reuse and can introduce unnecessary connection-management overhead.
The important point is that a long-lived client does not mean every request creates a new network connection.
That is normally a benefit, but it also means connection lifetime needs to be considered when infrastructure changes.
What Is Connection Eviction?
Connection eviction means removing a connection from the pool after a defined condition is reached.
One useful condition is age.
Conceptually:
The exact behavior depends on the HTTP handler and configuration being used.
The purpose is not to force a new connection for every request.
It is to periodically give the application an opportunity to establish a fresh connection.
Why DNS Failover Testing Matters
Suppose an application calls a backend service continuously.
At 10:00:
At 10:30, the backend fails and DNS is updated:
If the application keeps using an existing connection to 10.0.0.10, requests can continue failing until that connection is closed or becomes unusable.
Connection eviction provides one mechanism for limiting how long such connections remain in the pool.
However, it is not a replacement for proper retry, timeout, health-check, and failover strategies.
Configuring HttpClient
A typical HttpClient registration looks like this:
Connection lifetime settings are configured on the underlying HTTP handler.
For example, with SocketsHttpHandler:
The lifetime shown here is an example configuration, not a universal recommendation.
The correct value depends on DNS TTLs, service behavior, infrastructure, traffic patterns, and the application’s tolerance for reconnecting.
Choosing a Connection Lifetime
A common mistake is choosing an arbitrary lifetime such as five minutes and assuming that it guarantees reliable failover.
It does not.
The configuration should be based on the environment.
For example:
The goal is to balance two competing concerns.
Longer Connection Lifetime
Advantages:
- More connection reuse
- Fewer connection establishments
- Less connection-management overhead
Potential drawback:
- Existing connections can remain around longer
Shorter Connection Lifetime
Advantages:
- Connections are refreshed more frequently
- DNS changes can be discovered sooner through new connections
Potential drawback:
- More connection establishments
- Potentially higher connection-management overhead
There is no single value that is correct for every application.
Building a DNS Failover Test
A useful test environment should contain two backend endpoints.
For example:
The client uses:
Initially, DNS points to Service A.
The client sends repeated requests:
Then change the DNS record to Service B.
The test should continue sending requests and record which backend receives them.
This allows you to observe how the client behaves as connections age out and new connections are established.
Recording the Backend
Make each backend return an identifier.
For example:
Run the same application twice with different environment variables:
The client can then log the response:
This gives you a simple way to observe where requests are going.
Simulating DNS Changes
For a controlled local test, you can use a test DNS environment or host-level name resolution.
For example, a hosts file entry can be used for a simple local experiment:
For more realistic DNS behavior, use an actual DNS service or test environment where the record can be changed while the client remains active.
The important requirement is that the hostname stays the same while its destination changes.
If you simply change the URL from one server to another in the application, you are not testing DNS failover.
Testing Connection Eviction
Start with a long connection lifetime.
For example:
Start continuous requests:
Change DNS to backend B.
Continue the test.
Then repeat with a shorter lifetime:
The exact timing and observed behavior should come from the test environment.
The purpose is to compare how quickly new connections begin using the new destination.
Measuring Failover Behavior
Record at least these values:
| Metric | What It Tells You |
|---|---|
| DNS change time | When infrastructure changed |
| First new backend request | When new destination was observed |
| Failed requests | Impact during transition |
| Connection lifetime | Client configuration |
| Request interval | How frequently the client sends traffic |
| Recovery time | Time until normal behavior returns |
For example:
This makes the failover process easier to understand.
Connection Eviction Is Not a Failover Mechanism by Itself
This distinction is important.
Connection lifetime management can help an application discover infrastructure changes over time.
It does not guarantee that every request will succeed during a failure.
A production application should also consider:
- Timeouts
- Retries
- Retry limits
- Exponential backoff
- Circuit breakers
- Health checks
- Load balancers
- Service discovery
- Idempotency
For example, a failed payment request should not simply be retried blindly.
Retry behavior depends on whether the operation is safe to repeat.
Adding Timeouts
An HTTP client should have an appropriate timeout.
For example:
The value should reflect the actual service contract.
A timeout that is too short can generate unnecessary failures.
A timeout that is too long can keep resources occupied during a backend outage.
Adding Retry Logic Carefully
Transient failures may justify retry behavior.
However, retries should be bounded.
Conceptually:
Do not create an unlimited retry loop.
For write operations, verify that the operation is safe to repeat before automatically retrying it.
Common Mistakes
Assuming DNS Changes Existing Connections
DNS resolution and established connections are different things.
Changing a DNS record does not rewrite an already-open TCP connection.
Setting an Extremely Short Lifetime
A very short lifetime can increase connection establishment overhead.
The goal is controlled refresh, not constant reconnection.
Ignoring DNS TTL
Connection lifetime and DNS behavior should be considered together.
A client setting cannot compensate for an infrastructure design that is fundamentally inconsistent.
Testing by Changing the URL
Changing:
to:
does not test DNS failover.
The hostname must remain the same while its destination changes.
Relying Only on Connection Eviction
Connection eviction is one part of connection management.
It should not replace timeout and failure-handling strategies.
Troubleshooting
If the client does not appear to move to the new backend, check:
- Whether the DNS record actually changed.
- Whether the client is still using an existing connection.
- Whether the configured lifetime has elapsed.
- Whether a proxy is involved.
- Whether a load balancer is maintaining its own connections.
- Whether DNS caching exists elsewhere in the path.
- Whether the backend is actually reachable.
- Whether requests are being retried.
- Whether the client is using HTTP/1.1 or HTTP/2.
- Whether the test environment accurately represents production.
Network infrastructure can make this behavior more complicated than a simple DNS lookup.
HTTP/2 Considerations
Modern applications may use HTTP/2, where multiple requests can share a single connection.
That makes connection lifetime behavior particularly relevant because one connection can carry many concurrent requests.
The conceptual model becomes:
Closing or replacing that connection can affect multiple requests.
This is another reason not to choose connection lifetimes purely by guesswork.
Test the protocol and workload your application actually uses.
Production Considerations
Connection eviction should be considered together with the rest of the network architecture.
A typical production path might be:
There may be multiple layers of connection pooling and caching.
Changing PooledConnectionLifetime in the application does not necessarily control every connection in the architecture.
Document where DNS resolution occurs and where connections are pooled before using connection lifetime as a failover strategy.
Best Practices
Reuse HttpClient
Use IHttpClientFactory or an appropriately managed long-lived HttpClient.
Configure Connection Lifetime Deliberately
Choose a value based on infrastructure requirements rather than an arbitrary number.
Understand DNS Behavior
Know the DNS TTL and where DNS resolution occurs.
Use Timeouts
Every external dependency should have a reasonable timeout.
Handle Transient Failures
Use bounded retry strategies where appropriate.
Test Actual Failover
Change the destination behind the same hostname and observe real request behavior.
Monitor Failover
Production systems should expose enough telemetry to identify connection failures, backend changes, and recovery times.
Advantages
- Helps control how long pooled connections remain active.
- Can allow clients to establish fresh connections periodically.
- Useful when backend IP addresses can change.
- Works naturally with long-lived
HttpClientinstances. - Provides more control over connection-pool behavior.
Disadvantages
- Short lifetimes can increase connection-establishment overhead.
- Connection eviction alone does not guarantee successful failover.
- DNS, proxies, load balancers, and other infrastructure can affect the observed behavior.
- The correct lifetime depends on the deployment architecture.
- Poorly chosen settings can trade one problem for another.
Conclusion
Long-lived HTTP connections are an important performance feature, but they can become complicated when the destination behind a hostname changes.
.NET’s HTTP connection management provides ways to control how long pooled connections remain available. By configuring connection lifetime deliberately, an application can periodically establish fresh connections and give DNS changes an opportunity to take effect.
The right approach is not to choose the shortest possible lifetime.
Instead, understand the application’s DNS behavior, backend architecture, request frequency, HTTP protocol, and failure-handling requirements. Then test the actual failover scenario by changing the destination behind the same hostname.
Finally, treat connection eviction as one part of a broader reliability strategy. Timeouts, retries, health checks, load balancing, and service discovery still matter.
A controlled DNS failover test can reveal problems that normal functional testing will never expose, making it a useful addition to production-readiness testing for long-lived .NET APIs.
Best and Most Recommended ASP.NET Core 10.0 Hosting
Fortunately, there are a number of dependable and recommended web hosts available that can help you gain control of your website’s performance and improve your ASP.NET Core 10.0 web ranking. HostForLIFE.eu is highly recommended. In Europe, HostForLIFE.eu is the most popular option for first-time web hosts searching for an affordable plan. Their standard price begins at only €3.49 per month. Customers are permitted to choose quarterly and annual plans based on their preferences. HostForLIFE.eu guarantees “No Hidden Fees” and an industry-leading ’30 Days Cash Back’ policy. Customers who terminate their service within the first thirty days are eligible for a full refund.
By providing reseller hosting accounts, HostForLIFE.eu also gives its consumers the chance to generate income. You can purchase their reseller hosting account, host an unlimited number of websites on it, and even sell some of your hosting space to others. This is one of the most effective methods for making money online. They will take care of all your customers’ hosting needs, so you do not need to fret about hosting-related matters.