The Network Is No Longer Free: How Cloud Rewired My Coding Assumptions

For twenty years, I wrote code that assumed the network was fast, reliable, and effectively free. Not because I was naive — it was actually true. When your application and its database both live on the LAN, a query round-trip is measured in fractions of a millisecond. Connections are stable because nothing between them moves. The network is an implementation detail, not a variable you think about.

Cloud broke every one of those assumptions, and it took me an embarrassingly long time to fully internalize how much my code had been depending on them.

The LAN Assumption Is Baked Into Twenty Years of Patterns

Think about how SQL Server best practices evolved. "Avoid SELECT *" — partly about bandwidth, but really about reducing query plan work on a machine that was two rack units away. "Keep transactions short" — good practice, but the urgency increases dramatically when each round-trip is 2ms instead of 0.2ms. "Use connection pooling" — on a LAN, a new connection was cheap enough that sloppy connection management rarely showed in performance metrics.

In cloud-hosted database environments, the math changes. SQL Azure in 2011 was running in Microsoft's East US data center. Even a client with a good broadband connection in the same region was looking at 10–30ms round-trip latency to the database. That's not catastrophic in isolation, but multiply it by an application that opens a connection per request, runs 40 small queries, and closes the connection — all patterns that were invisible on a LAN — and you have an application that's suddenly 10–40× slower for no code changes.

The Specific Failure Modes

Chatty query patterns. An ORM that loads a parent object and then fires individual queries for each child (the classic N+1 problem) might have been acceptable at LAN latency. At WAN latency it's unusable. The fix — JOIN or batch the queries — was always the correct answer. Cloud made it mandatory.

Long-held connections. SQL Azure in 2011 would drop idle connections after a few minutes. Applications that held connections open between user requests — common in session-based web apps from the mid-2000s era — would get a Transport-level error... connection has been forcibly closed on the next request. On a LAN, this rarely happened because the LAN was stable; connections that were "idle" still kept the socket warm. On Azure, you got what the documentation said: idle connections get dropped.

No retry logic. Transient failures — brief network interruptions, Azure throttling under load, replica failover events — happen in cloud infrastructure and don't happen on a dedicated LAN. Application code written against a LAN assumption has no retry logic because it never needed any. Moving to cloud without adding retry logic is moving a car engine into a boat and wondering why it doesn't run.

What Needed to Change

Three categories of code changes made the difference for applications moving to SQL Azure:

1. Connection management. Use connection pooling correctly — open late, close early, don't hold across user interactions. In .NET, this meant using using blocks consistently and never passing SqlConnection objects around as long-lived members.

2. Retry policies. The Transient Fault Handling Application Block (later incorporated into the Enterprise Library) gave you a framework for wrapping database calls in retry logic with exponential backoff. This was not optional for SQL Azure production deployments.

// Transient fault handling pattern for SQL Azure
var retryPolicy = new RetryPolicy<SqlDatabaseTransientErrorDetectionStrategy>(
    RetryStrategy.DefaultExponential);

retryPolicy.ExecuteAction(() =>
{
    using (var conn = new SqlConnection(connectionString))
    {
        conn.Open();
        // your query here
    }
});

3. Query batching. Any pattern that ran N queries in a loop needed to be replaced with a single query using JOINs or table-valued parameters. What was a performance recommendation on a LAN was a correctness requirement at WAN latency.

The Data Practitioner Angle

SSIS packages and ETL pipelines had their own version of this problem. A package designed to move data between two LAN-connected SQL Servers, with dozens of small data flow tasks and lookup transformations hitting the source database, would perform completely differently against a cloud endpoint. Buffer sizes, batch commit intervals, connection timeout settings — all tuned for LAN assumptions, all wrong for WAN latency.

The principle held: anything that assumed a fast, free network needed to be reviewed before running against cloud infrastructure. In some cases, that meant redesigning the data flow. In others, it meant staging data locally before processing. The optimization that felt premature on a LAN was just correct architecture for cloud.

This shift in assumptions is one of the most fundamental changes cloud computing requires. It shows up differently in every type of application, but the underlying principle is the same: the network is a real thing now, with real costs and real failure modes. Write for it. As always, I'm here to help.

Read more