Familiar picture: short requests fly like swallows, but as soon as you start a large upload or download a hefty file through a mobile proxy, the connection drops halfway. The file is at 40 percent, then silence. Repeating the request sometimes helps, sometimes not. And the most annoying part: logs are silent, the server seems alive, but the data just doesn't arrive. If you've dealt with this, you've come to the right place.

This article is not about response codes or HTTP-level retry logic (there's a separate piece on 429 and exponential backoff that we'll refer to). Here we're diving into the transport layer: why TCP drops, who exactly kills the connection, how three different timeouts work along the packet path, what MTU and fragmentation in cellular networks are, and why a base station handover kills long sessions. And most importantly, we'll build a client that can survive all of it.

Introduction: Downloads Drop Midway, Short Requests Go Through

Why is this topic so relevant in 2026 specifically? Because mobile proxies have become a working tool for parsing, automation, testing, and working with marketplaces. A cellular network is inherently less stable than a wired one. It was designed for a person with a phone who opens a page, reads it, and closes it. It wasn't designed for a machine that keeps a single TCP connection open for ten minutes and streams a gigabyte through it.

Hence the paradox in the section title. Short requests go through because they finish before any timeout fires or a handover happens (switching between base stations). Long operations live longer, which raises the chance of hitting each problem: an idle timeout, a drop during cell reselection, or losing a large packet because of incorrect MTU.

Here's what you'll learn by reading to the end:

  • How to figure out in five minutes who exactly dropped the connection: your client, the proxy, the carrier, or the target server.
  • How TCP keepalive is fundamentally different from HTTP keep-alive, and why you need both settings.
  • How to measure the three timeouts along the path and find the shortest one that decides the connection's fate.
  • Why MTU is lower than the standard 1500 bytes in cellular networks, and what PMTUD breakage looks like (symptom: hanging on large responses).
  • Ready-to-use client code in Python and Node with Range resuming, upload chunking, and proper timeouts.

We'll speak technically, but every term will be explained in plain language. Let's go.

Basics: How a Connection Through a Mobile Proxy Works

Before we dig into failures, let's agree on the big picture. When you make a request through a mobile proxy, the packet travels a long chain. Understanding this chain is half the battle in diagnostics.

Packet Path from Client to Server

Imagine a package's route. It moves through stages, and at each one it can be delayed or lost:

  1. Your client - the program making the request. It has its own timeouts and socket settings.
  2. Proxy server - accepts your connection and opens its own to the destination. Often this is two different TCP connections glued together.
  3. Mobile modem and radio interface - the narrow, finicky stretch. Here the packet travels over the air to the base station.
  4. Carrier core network - NAT, gateways, traffic prioritization systems.
  5. Public internet - backbone links to the destination's data center.
  6. Target server - the endpoint, which also has its own connection length limits.

Key insight: a connection through a proxy isn't one pipe, but at least two. Your client holds a connection to the proxy, and the proxy holds a connection to the destination. A break can happen on any of these segments, and the symptoms will differ.

What a Session Is and Why It's Fragile

A TCP connection is a virtual channel. There's no physical wire between you and the server: it's an agreement between two parties to exchange numbered bytes. As long as both sides remember the numbers and state, the connection is alive. As soon as one side forgets the state (NAT reloaded, a timeout expired, a cell changed), the connection is effectively dead, even though the other side might not find out for a long time.

This is exactly what creates nasty half-open connections: one side thinks the channel is alive and waits for data, while the other has forgotten everything long ago. The client hangs, no error arrives, and time passes. Sound familiar?

The Three Levels Where Problems Occur

  • Radio level - packet loss, latency, cell changes. The nature of cellular communication.
  • Network level - carrier NAT timeouts, MTU, fragmentation.
  • Application level - HTTP server timeouts on the proxy and destination, limits on response body size.

Next, we'll go through each one and learn how to tell them apart.

Deep Dive: Who Can Drop the Connection and How to Tell Who Did It

This is the most important diagnostic section. Until you know the culprit, you're shooting in the dark. Good news: each culprit leaves a distinct fingerprint.

The Four Suspects

1. Your client. The most common and most underestimated culprit. HTTP libraries have default timeouts you might not have noticed. For example, a timeout on total request time, a socket read timeout, an idle timeout. If your client dropped the connection itself, logs will show an error like read timeout or socket timeout with your code in the stack trace.

2. Proxy server. Proxies have their own limits: maximum connection lifetime, idle timeout, maximum response size. When a proxy kills the connection, you often get a sudden connection reset or a close without a response in the middle of the body. Meanwhile, ping to the proxy works, and short requests succeed.

3. Mobile carrier. The most invisible one. Carrier NAT tables have a record lifetime. If no traffic flows through a connection for a while, the carrier deletes the NAT entry, and there's simply nowhere to deliver subsequent packets. Symptom: the connection hangs precisely during pauses, not during active transfer. The carrier is also the culprit during base station handovers.

4. Target server. It has its own keep-alive settings and limits. Many servers close connections after N requests or T seconds. Symptom: the server sends a Connection: close header or gracefully finishes the connection (FIN) rather than resetting it (RST).

Symptom-Based Diagnosis: A Table of Fingerprints

Let's look at the telltale signs so you can identify the culprit in minutes.

  • Break happens strictly during pauses; everything is fine during active transfer - almost certainly a carrier NAT timeout or a proxy idle timeout. Fixed with keepalive traffic.
  • Break always happens at roughly the same data volume (for example, around 8 or 10 megabytes) - a response size limit on the proxy or server. Fixed by chunking with Range.
  • Break always happens at roughly the same time (for example, exactly 60 or 300 seconds) - a hard limit on connection lifetime. Look for the smallest of the timeouts.
  • Hanging specifically on large responses, small ones pass - classic PMTUD breakage and an MTU problem. There's a whole section on this below.
  • Random breaks unrelated to volume or time, more frequent when moving - base station handover, cell change, radio signal degradation.
  • Instant RST when trying to send data - the connection is already dead on one side (half-open), or the proxy is actively resetting it.

Primary Diagnostic Tools

To tell FIN (polite close) from RST (rough reset) and understand which segment is breaking, use:

  • Socket-level logging - record the exact time of the break, the number of bytes transferred, and the exception type.
  • Traffic analysis - a packet capture utility will show who sent RST or FIN. If the RST comes from the proxy's address, the proxy is at fault. If the connection just goes silent with no packets, an intermediate node (the carrier) is at fault.
  • Control measurements - repeat the same operation over a wired connection directly. If everything is stable over wired and it drops through the mobile proxy, the problem is in the mobile segment.

From the author's experience: in 70 percent of cases we've analyzed, the culprit was a carrier NAT timeout or a default idle timeout, not the proxy or the server. People blame the proxy, but the fix is a couple of lines of socket settings.

Keep-alive and Idle Timeout: Three Timeouts Along the Path, the Shortest One Wins

Here's a fundamental principle worth tattooing on your brain: there are several independent idle timeouts along the packet path, and the shortest one decides the connection's fate. It's like a chain: it breaks at the weakest link.

Where the Timeouts Live

  1. Your client's idle timeout. How long your program is willing to wait for data without receiving anything. Defaults across libraries range from 30 seconds to infinity.
  2. Proxy idle timeout. How long the proxy keeps an idle connection open. Typical values are 60 to 300 seconds.
  3. Carrier NAT timeout. How long the network core keeps an address translation entry without traffic. For TCP it's often 300-600 seconds, but for UDP and during peak hours it can be 30-60 seconds.
  4. Target server keep-alive timeout. How long the server holds a connection between requests. Often 5-75 seconds.

Imagine your client is willing to wait 120 seconds, the proxy drops at 90, and the carrier cleans up NAT at 60. Who wins? The carrier. The connection dies at the 60th second of idle time, and neither the client nor the proxy will know right away.

How to Measure the Shortest Timeout

The method is simple and reliable. Establish a connection, make one request, then go quiet and wait, timing how long until the drop. Repeat a few times to rule out randomness.

  1. Open a connection through the proxy to a test server that supports keep-alive.
  2. Make one short request and get the response.
  3. Don't close the connection. Start a timer.
  4. Periodically (once per second) check if the connection is alive by trying to read from the socket in non-blocking mode.
  5. Note the moment when an RST, FIN arrives or the socket becomes unreadable.

Run the measurement three times. If the break consistently happens around 60 seconds, that's your idle ceiling. That means keepalive traffic needs to be sent more often than every 60 seconds, with a good margin - for example, every 20-25 seconds.

Strategy for Beating Idle Timeout

Since the shortest timeout decides everything, our job is to never let the connection sit idle longer than that limit. Two approaches:

  • Fill the connection with useful traffic - during active data transfer, idle timeouts don't fire because there's no idle time. That's why a continuous download rarely suffers from idle timeout, but it does suffer from size and lifetime limits.
  • Send keepalive probes during pauses - when there's no useful data (for example, you're waiting for a report to be generated on the server), you need to keep the connection alive with artificial traffic. This is where the two keep-alive mechanisms come in, which we'll cover separately.

TCP Keepalive vs. HTTP Keep-Alive: Different Mechanisms, You Need Both

A huge amount of confusion in the industry comes from the similar names. TCP keepalive and HTTP keep-alive are completely different things operating at different levels. And a resilient mobile client needs both.

HTTP Keep-Alive: Connection Reuse

HTTP keep-alive (also known as a persistent connection) is about not opening a new TCP connection for every request. Instead, one connection serves several requests in a row. This is the application level.

Why does this matter for mobile networks? Establishing a new TCP connection over a cellular network is expensive. The three-way handshake, plus a TLS handshake if encryption is used, can take hundreds of milliseconds over a high-latency radio link. By reusing a connection, you save that time on every subsequent request.

But! HTTP keep-alive does nothing to protect against a carrier NAT timeout during pauses. It just keeps the connection open for the next request, but it doesn't generate traffic in between on its own.

TCP Keepalive: A Pulse at the Transport Level

TCP keepalive is a mechanism of the TCP protocol itself. The operating system periodically sends an empty probe packet to check whether the other side is alive and, along the way, refresh entries in intermediate NAT tables. This is the OS kernel level.

TCP keepalive is your primary weapon against carrier NAT timeouts and idle timeouts on intermediate nodes. Each probe is traffic that resets the idle counter along the entire path.

TCP keepalive has three key parameters:

  • keepalive idle (or keepalive time) - how many seconds of inactivity before probes start. The default in most OSes is 7200 seconds, i.e., two hours. A disaster for mobile networks.
  • keepalive interval - the interval between probes if there's no response.
  • keepalive count (probes) - how many unanswered probes in a row indicate a dead connection.

Recommended Values for Mobile Networks

The default two hours are absolutely useless. The carrier will clean up NAT long before the first probe. Here are working values proven in practice:

  • keepalive idle: 15-25 seconds. Start sending probes after a short pause to reliably stay ahead of even the most aggressive NAT timeout.
  • keepalive interval: 10-15 seconds. If a probe doesn't get through, repeat after a short interval.
  • keepalive count: 3-4. After three or four unanswered probes, declare the connection dead and re-establish it instead of hanging forever.

This combination gives a double benefit: the connection doesn't get killed by the carrier during pauses, and if it does die anyway (say, due to a handover), the client finds out within 45-70 seconds instead of hours. Fast dead-connection detection is half of resilience.

Why You Need Both Settings

An analogy. HTTP keep-alive is like keeping a meeting room booked all day so you don't have to re-book it every time. TCP keepalive is periodically walking into that room so the janitor doesn't decide it's empty and lock it. Book it but never visit - they'll lock it. Visit it but re-book every time - you waste time. You need both.

MTU and Fragmentation: Why Packets Are Smaller in Cellular Networks

Now let's move to the most underestimated cause of hangs. If small responses pass and large ones hang for good - there's a 90 percent chance it's MTU and broken PMTUD.

What MTU Is in Plain Terms

MTU (Maximum Transmission Unit) is the maximum size of a single packet that can be sent into the network without fragmentation. Classic Ethernet is 1500 bytes. Think of it as the width of a doorway: furniture wider than the door has to be taken apart to fit through.

The problem is that the effective MTU in cellular networks is often lower than 1500. The reason is encapsulation. Mobile traffic gets wrapped in additional protocol layers inside the carrier's network. Each layer adds its own header bytes, leaving less room for payload. The real working MTU in mobile networks often lands in the 1400-1480 byte range, and sometimes lower.

What PMTUD Is and Why It Breaks

PMTUD (Path MTU Discovery) is a mechanism for automatically finding the maximum packet size along the whole path. Here's how it works: the client sends a large packet with the Don't Fragment flag. If a node with a smaller MTU is encountered along the way, that node drops the packet and sends back a special ICMP message like "fragmentation needed" with the allowed size. The client gets the hint and lowers its packet size.

A neat scheme. But it hinges on one fragile condition: ICMP messages must make it back to the client. In reality, many networks, firewalls, and security settings block ICMP entirely. And that's where the disaster called a PMTUD black hole happens.

What PMTUD Breakage Looks Like: Anatomy of a Hang

The scenario is classic and easy to recognize:

  1. The client establishes a connection. The handshake uses small packets - all good.
  2. The client sends a short request - the small packet goes through, and a response comes back. Small responses work.
  3. The server starts sending a large response with full-size 1500-byte packets carrying the Don't Fragment flag.
  4. Somewhere along the path, a node with an MTU of 1400 drops those packets because they're too big and can't be fragmented.
  5. The node sends back an ICMP "fragmentation needed" message, but that ICMP is blocked by a firewall and never arrives.
  6. The server doesn't get the hint, keeps sending the same large packets, and they keep getting dropped. Endless loop.
  7. Result: small packets (headers, ACKs) get through, but the response data doesn't. The connection hangs forever in the middle of a large response.

That's why short requests pass while large responses hang. It's not mysticism; it's a PMTUD black hole. And it's arguably the most frequent source of gray hairs for engineers working with mobile traffic.

How to Fix MTU Problems

There are several levels of solutions, from application-level to network-level:

  • MSS clamping. The most reliable method at the network level. MSS (Maximum Segment Size) is the maximum TCP segment size that the two sides agree on at the very beginning, during the handshake. If you explicitly limit MSS so the resulting packet fits within the real MTU (for example, MSS 1360-1400), the server will send properly sized packets from the start, and no ICMP is needed. This fixes the black hole at its root.
  • Lower the interface MTU. If you control the modem or the machine carrying the traffic, you can set the interface MTU to 1400 or lower. Then all outgoing packets are guaranteed to be no larger than the safe size.
  • Allow ICMP to pass. If you control firewalls along the path, allow "fragmentation needed" ICMP messages. Then standard PMTUD works as intended.
  • Application level. If you're downloading a large file, split it into parts using Range requests. Each part is a separate, short transfer that's far less likely to hit large-stream problems. More on this in the practical section.

Key insight: even if you don't control the network, you can almost always affect MSS through connection settings or through your proxy service parameters. A good mobile proxy provider already sets up proper MSS clamping on their side, saving you from black holes. This is one of the criteria for service quality.

Base Station Handover and Network Transitions: Why TCP Doesn't Survive Them

Now for the most fundamental incompatibility. Cellular networks are built for mobility, and TCP is not. It's a conflict at the architectural level.

Why TCP Is Bound to an Address

A TCP connection is uniquely identified by a four-tuple: source address, source port, destination address, destination port. It's like the mailing address of the connection. If any one element changes, it's already a different connection, and the old one becomes invalid.

What happens in a mobile network? In some base station handover scenarios, or when switching between technologies (for example, between generations of mobile networks, or between networks), the mobile node's external IP address can change. And here TCP is powerless: it can't continue a connection with a new address. The old connection is simply dead. Any data in flight is lost.

Handover: Not Always Fatal, But Always Risky

To be fair, modern networks try hard to make handovers seamless: keeping the same IP when switching cells. Often they succeed, and you don't notice the switch. But sometimes there's an IP change, a one-to-two-second radio gap, or a burst of packet loss. For a short request, this is invisible. For a ten-minute session, it's a lottery you play every time.

Symptoms of a Handover Break

  • Breaks are random, with no connection to data volume or time.
  • The break frequency increases if the device physically moves (which is typical for mobile proxies on real SIMs).
  • After a break, a new connection establishes fine - the network is alive; only the specific old connection died.

What to Do About It: Accept It and Build Resilience

You can't beat an IP change at the TCP level. But you can build a client for which a connection break is a normal situation, not an emergency. The philosophy is simple: a connection over a mobile network is ephemeral by definition, and a client must be able to seamlessly re-establish it and pick up where it left off.

Here are the specific techniques we'll implement in code:

  • Idempotent operations. Design requests so they can be safely retried. Range downloads are idempotent: requesting the same byte range again gives the same result.
  • Resume, don't restart. On a break, don't start the file over; continue from the last byte received. Saves traffic and time.
  • Fast dead-connection detection. With the aggressive TCP keepalive we've discussed, you learn about a dead connection in seconds, not minutes.
  • Short transactions. The shorter an individual transfer is, the less likely a handover will hit it. Chunking a large upload is a direct consequence of this principle.

Python in Practice: A Resilient Client with Resume and Timeouts

Enough theory, let's build. We'll start with Python. We'll create a client that configures TCP keepalive, sets sensible timeouts, downloads a file in parts via Range, and can resume after a break.

Step 1: Configuring TCP Keepalive on the Socket

Standard HTTP libraries don't set aggressive keepalive out of the box. You need to get down to the socket. In the requests ecosystem, this is done with a custom transport adapter that sets socket options: enables keepalive, sets idle to 20 seconds, interval to 10 seconds, and count to 3. At the description level, the logic is this: we register an adapter that applies the needed parameters at a low level when a connection is created.

The meaningful part of the setup in plain pseudocode: enable the SO_KEEPALIVE option, then set TCP_KEEPIDLE to 20, TCP_KEEPINTVL to 10, and TCP_KEEPCNT to 3. Option names differ slightly across operating systems, so in production you should choose them with a platform check.

Step 2: Sensible Timeouts

Key rule: always set timeouts explicitly and separate the connection timeout from the read timeout. The no-timeout default is a trap where the client hangs forever on a half-open connection.

  • Connect timeout: 10 seconds. Setting up a connection over a mobile network is slower, but 10 seconds is enough with margin.
  • Read timeout: 30 seconds. This is a timeout for inactivity between chunks of data, not for the whole transfer. If no byte arrives in 30 seconds, we consider the connection problematic.
  • Overall operation budget should be controlled separately in your resume logic, not with one giant timeout for the entire request.

Step 3: Range Download with Resume

Here's the algorithm. We open the target file for writing. We find out how much has already been downloaded (if the file partially exists). We request the remaining range with a Range: bytes header from the current position to the end. We write the stream to the file as it arrives. If we catch a break (read exception, connection drop), we don't panic: we look again at how many bytes are on disk and repeat the request from the new starting position. We keep going until the file is fully received.

Step-by-step logic in words:

  1. Determine the total file size with a headers request (HEAD or a GET with Range: bytes=0-0 to read Content-Range).
  2. Check the local size of the already downloaded portion.
  3. If the local size equals the total, the file is ready; exit.
  4. Otherwise, build a request with a Range starting at the local size.
  5. Read the response in 64-256 KB chunks, appending to the file.
  6. On successful completion, verify integrity (size, and a checksum when possible).
  7. On a break, increment the attempt counter, apply a short pause, and go back to step 2.
  8. Cap the maximum number of transport-level attempts (for example, 5-8) so you don't loop forever during a systemic problem.

An important nuance: make sure the server supports Range. The signs are an Accept-Ranges: bytes header in the response and a 206 Partial Content status for a Range request. If the server returns 200 and ignores Range, resuming isn't possible, and you'll have to download from scratch; in that case, keepalive and correct MSS become especially important.

Step 4: Chunking Large Uploads

When you're not downloading but uploading a large volume (for example, sending data or receiving a large report), apply the same chunking principle. Break the task into pages or fixed-size chunks. Each chunk is a separate short transaction with its own error handling. Keep a progress log of which chunks have been confirmed. On a break, retry only the unconfirmed ones. This turns one fragile ten-minute operation into a series of resilient short ones.

As for retry strategies based on server response codes, we won't cover them here because that's the topic of a separate piece on 429 and exponential backoff, which you should read after this article. Our focus is transport: breaks, timeouts, and size.

Node.js in Practice: A Resilient HTTP Agent and Streaming

Now the same set of principles in the Node.js ecosystem. Here, the agent object, which manages the connection pool, plays the central role.

Step 1: Configuring an Agent with Keep-Alive

In Node, you create an HTTP or HTTPS agent with keepAlive enabled. The keepAlive: true parameter makes the agent reuse connections (that's the HTTP level). You also set keepAliveMsecs - the interval at which TCP keepalive probes are sent at the socket level. For mobile networks, set keepAliveMsecs to around 15000-20000 milliseconds to stay ahead of the carrier's NAT timeout. Also limit maxSockets and maxFreeSockets to avoid spawning unnecessary connections.

Step 2: Timeouts at Different Levels

In Node, timeouts are set in several places, and it's important not to miss any:

  • Connection establishment timeout - via an option on the request or through a socket connection event handler.
  • Socket idle timeout - a method that sets a socket timeout. When it fires, you need to explicitly destroy the socket and treat it as a break. Node doesn't close the socket automatically on timeout; it only emits an event - this is often forgotten, and the connection keeps hanging.
  • Handling error and close events on both the request and the socket - each should lead to controlled retry logic.

Recommended values are similar to Python: connect around 10 seconds, socket idle around 30 seconds, keepalive probes every 15-20 seconds.

Step 3: Streaming Downloads with Resume

In Node, it's natural to work with streams. The resume logic is the same as in Python: check the local file size, open a write stream in append mode, build a request with a Range header starting at the current size, and attach handlers for data, end, and error events. On data, write the chunk to the file. On end, check whether the entire file has been received. On error, or on a premature close when less than expected was received, trigger a retry from the new position.

The key resilience point in Node is correct handling of premature stream completion. The end event can fire even if not everything was received, if the connection dropped. So always verify the actual received volume against the expected volume from the Content-Length or Content-Range header. Don't rely solely on the end event firing.

Step 4: A Transport-Level Retry Wrapper

Wrap the entire download operation in a loop with a limited number of attempts. Between attempts, use a short pause (1-3 seconds is enough for transport breaks, because the cause isn't server overload but a network event). Count attempts. When the limit is exhausted, throw the error upward with diagnostic information: how many bytes were received, what error type occurred, and how many attempts were made. This diagnostics is invaluable when investigating incidents.

Common Mistakes: What Not to Do

Let's look at the anti-patterns we regularly see in other people's code. Avoid them, and half your problems will disappear.

Mistake 1: No Explicit Timeouts

The most common and the most painful. A client without a timeout on a half-open connection hangs forever. The thread is blocked, resources aren't freed, and you think the operation is still running. Always set timeouts explicitly. No timeout isn't infinite patience; it's a hidden bomb.

Mistake 2: Relying on the Default TCP Keepalive

The default two hours make TCP keepalive useless for mobile networks. Many people enable SO_KEEPALIVE and relax, not realizing the first probe won't go out for 7200 seconds, long after the carrier has cleaned everything up. Set idle, interval, and count explicitly.

Mistake 3: Re-Downloading the Whole File on Every Break

Breaking at 95 percent and restarting from zero wastes not just time but also mobile traffic, which proxies usually bill by volume. Range-based resuming is a must for any large download.

Mistake 4: Ignoring MTU and MSS

People spend months fighting hangs on large responses, trying different timeouts and proxies, when the cause is a PMTUD black hole. If large responses hang and small ones pass - check MTU and configure MSS clamping first. It'll save you weeks.

Mistake 5: Confusing Transport Breaks with Server Responses

A transport break (RST, read timeout, dead socket) and a server response with an error code are different situations requiring different response strategies. For transport breaks, quick retries with a short pause and resume are appropriate. For server responses with codes like 429, you need exponential backoff - and that's a separate article's topic. Don't mix these two layers in a single handler.

Mistake 6: Too-Aggressive Retries

An infinite retry loop with no limit during a systemic problem (for example, when a proxy is completely unavailable) turns into parasitic load. Always cap the number of attempts and finish the operation gracefully with diagnostics.

Mistake 7: Not Verifying Result Integrity

The fact that a download finished doesn't mean you got correct data. A break can leave a truncated file that looks complete by every formal measure. Always check the size, and for important data, a checksum.

Mistake 8: Holding One Connection Too Long

The longer a mobile network connection lives, the higher the cumulative chance of hitting a handover, IP change, or NAT timeout. Periodically re-establishing a connection isn't a weakness; it's sensible hygiene. Don't be afraid to recreate connections.

Tools and Resources for Diagnostics and Building Resilience

The right tool saves hours. Here's an arsenal worth keeping on hand.

Network and Packet Diagnostics

  • Packet capture and analysis. A packet capture tool is your microscope. It shows who sent RST, whether an ICMP "fragmentation needed" message got through, what size packets actually go over the wire, and where the stream breaks. Without it, MTU diagnostics and identifying the culprit of a break turn into guesswork.
  • Path-checking utilities. Traceroute and MTU-checking tools help you understand where on the path the packet size gets too big. There are modes that deliberately look for the maximum achievable packet size - exactly what you need for MSS tuning.
  • Test echo servers. A simple server that supports keep-alive and can return data of a specified size is invaluable for measuring idle timeouts and reproducing large-response problems under controlled conditions.

Client Libraries and Approaches

  • HTTP clients with flexible socket configuration. Choose libraries that give you access to connection parameters and let you set timeouts and keepalive at a low level.
  • Streaming mechanisms. Streaming the response body is mandatory for large downloads - you shouldn't hold the entire response in memory.
  • Progress logging. A simple state store (which chunks are done, how many bytes are on disk) turns resuming into a trivial task.

Proxy Infrastructure Quality

Let's emphasize this separately: a significant share of transport problems is solved on the side of a quality proxy provider. Properly configured MSS clamping, reasonable idle timeouts, stable IP retention during handovers, and transparent keep-alive handling are all signs of a mature service. Services like MobileProxy.space design their infrastructure with these transport nuances in mind, which removes some of the headache from the client. But even with an ideal proxy, your client still needs to be resilient - because the radio channel is unpredictable by nature.

Case Studies and Results: How This Works in Practice

Let's walk through a few summarized cases that reflect typical situations and their solutions. The numbers are averaged, but they reflect real orders of magnitude.

Case 1: Catalog Upload Hung Midway

Situation. A team was uploading a large product catalog through a mobile proxy in a single request. The response was around 15 megabytes. It consistently hung around 6-8 megabytes, with no error, just silence until a global timeout fired after a few minutes.

Diagnostics. Small requests passed perfectly. Packet capture showed that large packets were going out with the Don't Fragment flag, and no ICMP "fragmentation needed" came back. A classic PMTUD black hole.

Solution. We configured MSS clamping to a value that guaranteed packets fit within the mobile network's real MTU, and also split the upload into page-based requests of 2 megabytes each.

Result. The hangs completely disappeared. Upload time became predictable, and on rare breaks only one page had to be retried, not the entire catalog. The success rate for uploads rose from around 40 percent to effectively 100 percent.

Case 2: The Connection Died During Waiting Pauses

Situation. A client sent a request to generate a heavy report; the server took 90-120 seconds to think and was then supposed to return the result. But by the time the report was ready, the connection was already dead.

Diagnostics. Measuring the idle timeout showed a consistent break at around 60 seconds of inactivity. The culprit was the carrier's NAT timeout: there was no traffic at all while waiting.

Solution. We enabled TCP keepalive with idle of 20 seconds and interval of 10. Now, while waiting, the connection was refreshed with keepalive probes every 20 seconds.

Result. The connection survived until the report was ready. Breaks during pauses stopped. A bonus: the client began detecting truly dead connections within 45-60 seconds instead of hanging for minutes.

Case 3: Random Breaks During Active Scraping

Situation. Long-lived scraping sessions broke erratically, unrelated to volume or time. Especially often during certain hours.

Diagnostics. The signs pointed to an IP change during a handover. After a break, a new connection came up instantly - the network was alive.

Solution. We reworked the client around the ephemeral-connection philosophy: short idempotent transactions, a progress log, fast connection re-establishment on breaks, and limited retries with short pauses.

Result. The breaks didn't physically go away (you can't beat an IP change), but they stopped being a problem. Each break cost one short transaction retry - a fraction of a second. Overall process reliability jumped dramatically, and engineers stopped sitting by the logs at night.

Takeaway from the Cases

Notice the pattern: in every case, the solution wasn't changing the proxy, but understanding the transport layer and configuring the client properly. Symptom-based diagnostics pointed to a specific culprit, and the fix was targeted and fast.

FAQ: Common Questions About Mobile Network Connection Drops

Why do short requests work through a mobile proxy while long ones break?

Because long operations live longer and manage to hit every transport problem: idle timeouts during pauses, response size limits, connection lifetime limits, handovers with IP changes, and PMTUD black holes on large packets. Short requests finish before any of these can fire. The solution is to configure keepalive, MSS, and implement Range-based resuming.

How do I tell who exactly is dropping the connection - the proxy, the carrier, or the server?

Look at the fingerprint. Breaks during pauses mean a carrier NAT timeout or a proxy idle timeout. Breaks at a fixed volume mean a size limit on the proxy or server. Breaks at a fixed time mean a lifetime limit. Hanging on large responses points to MTU and PMTUD. Random breaks while moving suggest a handover. For a definitive answer, use packet capture: it will show which address sent the RST and whether ICMP got through.

What's the difference between TCP keepalive and HTTP keep-alive?

HTTP keep-alive works at the application level and lets you reuse one connection for multiple requests, saving setup overhead. TCP keepalive works at the OS kernel level and periodically sends probe packets to keep the connection alive during pauses and refresh NAT entries. The first saves time on new requests; the second saves the connection from dying during idle time. You need both.

What TCP keepalive values should I set for mobile networks?

A good starting point: idle 15-25 seconds, interval 10-15 seconds, count 3-4. This combination stays ahead of aggressive carrier NAT timeouts and also gives you fast dead-connection detection. Fine-tune the exact values by measuring your idle timeout on your specific carrier and proxy.

What is a PMTUD black hole and how do I recognize it?

It's a situation where a node along the path drops packets that are too large, but its ICMP notice telling the sender to reduce the size is blocked and never arrives. As a result, large packets are lost endlessly while small ones pass. You recognize it by the symptom: the handshake and small responses work, but large responses hang indefinitely. It's fixed with MSS clamping or a lower MTU.

Can a TCP connection survive a base station handover?

If the network keeps the same external IP during the handover, yes - the connection will survive, possibly with a short delay. If the IP changes, no - the old TCP connection is irreversibly dead because TCP is strictly bound to the address and port pair. The right strategy isn't to preserve the connection at any cost, but to build a client that seamlessly re-establishes the connection and picks up from where it broke.

What's the right way to resume a file after a break?

First, check if the server supports Range (look for an Accept-Ranges: bytes header and a 206 response to a Range request). Then, after a break, determine the size of the already downloaded portion and request the remainder with a Range header starting from that byte, appending to the same file. Repeat until the file is fully received, capping the number of attempts. Finally, always verify the final size against the expected one.

What timeouts should I set in an HTTP client for a mobile proxy?

Separate the connection timeout (around 10 seconds) from the read idle timeout (around 30 seconds, meaning a pause between data chunks, not the whole transfer). Control the overall operation budget in your resume logic rather than with one huge request timeout. Never leave timeouts unlimited.

Do I need to change anything if retry strategies based on response codes are already configured?

Yes. Response-code retries (like handling 429 with exponential backoff) are the application layer - a separate topic. Transport breaks - RST, read timeouts, dead sockets - need their own logic: quick retries with short pauses, resuming, keepalive, and correct MSS. These two layers don't replace each other and should coexist in your client.

Does the choice of proxy provider affect transport resilience?

Significantly. A mature provider configures MSS clamping, reasonable idle timeouts, tries to keep IPs stable during handovers, and handles keep-alive properly. That removes part of the problem before it reaches your code. But even a perfect proxy doesn't eliminate the need for a resilient client, because the radio channel is unpredictable by nature.

Conclusion: The Connection Is Ephemeral, but the Data Must Get Through

We've walked the path from symptom to a resilient client. Let's lock in the key points so this article becomes your bookmark.

First. A long connection drop through a mobile proxy isn't mysticism; it's the result of very concrete mechanisms: idle timeouts at three levels, size and lifetime limits, MTU issues, and handovers. Each leaves a distinct fingerprint, and symptom-based diagnostics almost always identifies the culprit.

Second. The shortest timeout along the path decides the connection's fate. Measure it and set TCP keepalive more aggressively than that limit - idle 15-25 seconds for mobile networks. Don't forget that TCP keepalive and HTTP keep-alive are different mechanisms, and you need both.

Third. If large responses hang while small ones pass, it's almost certainly a PMTUD black hole. Fix it with MSS clamping and correct MTU. Don't waste weeks tweaking timeouts; check the packet size first.

Fourth. You can't beat an IP change during a handover, but you can make it harmless. Build your client around the ephemeral nature of the connection: short idempotent transactions, Range-based resuming, a progress log, quick re-establishment, limited retries, and mandatory integrity checks.

Your next steps are simple. Measure the idle timeout on your proxy and carrier. Enable and configure TCP keepalive. Test behavior on large responses and configure MSS if needed. Implement Range-based resuming. And definitely read the related material on response-code retry strategies - 429 and exponential backoff - so you cover the application layer as well, not just the transport layer.

A mobile network is unpredictable by nature. But a client built with respect for that nature turns the unpredictability from a source of late-night alarm calls into routine background noise. The connection is ephemeral - and that's okay. What matters is that the data still gets through. Now you know how to make that happen.