Why architecture matters here

Two forces make single-path TCP inadequate on modern endpoints, and both are architectural, not incidental. First, hosts are increasingly multi-homed: a phone has Wi-Fi and cellular, a server has multiple NICs, a datacenter fabric offers many equal-cost routes. Single-path TCP can use exactly one of these per connection, so the others are wasted capacity and wasted resilience. Second, paths change: signal fades, links fail, a user moves between networks. TCP's binding of a connection to an address pair means any such change is fatal to the connection — the classic dropped download when you leave the coffee shop. MPTCP exists to convert both the wasted capacity and the fragility into usable throughput and seamless continuity.

But the reason MPTCP's architecture is intricate rather than obvious is the constraint it operates under: it cannot change the applications above it or the network below it. Above, millions of programs call the same socket API expecting one in-order reliable stream, so MPTCP must preserve that abstraction exactly — no application should need rewriting to benefit. Below, the path from client to server is littered with middleboxes that assume TCP's every field means what it always meant; a protocol that put multipath signaling somewhere visible would be mangled or dropped. So MPTCP threads a needle: it signals entirely within TCP options, makes each subflow look exactly like an ordinary TCP connection to any middlebox inspecting it, and carries a second, connection-level sequence space that only the endpoints understand.

That constraint is why fairness and fallback are load-bearing rather than nice-to-have. Fairness: because each subflow is real TCP, two of them naively would grab twice a fair share at a shared bottleneck; MPTCP must couple their congestion control so the aggregate behaves like one flow where paths overlap and like independent flows where they don't. Fallback: because any path might traverse a middlebox that strips options or rewrites sequence numbers, MPTCP must detect the breakage and drop back to plain TCP on that subflow without corrupting the stream. An engineer who understands these two mechanisms understands why MPTCP works in the real, hostile Internet and not just on a whiteboard.

Advertisement

The architecture: every piece explained

Top row: the connection and its subflows. An MPTCP connection is the single logical stream the application owns. It begins as one TCP handshake carrying the MP_CAPABLE option, through which both ends confirm MPTCP support and exchange keys; that first successful TCP connection becomes the initial subflow. Additional subflows — Subflow A, B, ... — are ordinary TCP connections over different paths, each joined to the existing MPTCP connection with the MP_JOIN option and authenticated using the exchanged keys so a stranger cannot inject a subflow. The path manager is the policy that decides which subflows exist: it discovers additional addresses (announced via ADD_ADDR), and initiates or accepts new subflows — full-mesh, or a conservative single-backup, depending on configuration and role.

Middle row: the machinery that keeps one ordered stream out of many paths. The crux is two sequence spaces. Each subflow has its own ordinary subflow sequence numbers, so to any middlebox it is a normal, contiguous TCP flow. Overlaid on top is the data sequence number (DSN), a connection-level sequence carried in the DSS option that maps each subflow's bytes back to their position in the single application stream. The packet scheduler decides, for each segment the application writes, which subflow carries it — typically preferring the lowest-latency path with available congestion window, and reinjecting a segment onto another subflow if the first stalls. At the far end, receive reassembly uses the DSNs to reorder bytes arriving out of order across paths into the single in-order stream the receiving application reads.

Bottom rows: survival and fairness. Middlebox handling is the fallback logic: if the MP_CAPABLE handshake is stripped or a path mangles the DSS mapping, MPTCP gives up multipath on that connection or subflow and behaves as plain TCP, never corrupting data to preserve multipath. Coupled congestion control (algorithms such as LIA, OLIA, or BALIA) links the congestion windows across subflows so the connection takes no more than its fair share where paths share a bottleneck, while still shifting traffic toward less-congested paths. The ops strip lists what operators actually watch: per-path health, scheduler behavior, the rate at which connections fall back to single-path, and reinjection statistics that reveal path asymmetry problems.

Multipath TCP — one connection, many paths: use every network interface at oncea single byte stream split across subflows over Wi-Fi, cellular, and wired linksMPTCP connectionone logical streamSubflow Aregular TCP over path 1Subflow Bregular TCP over path 2Path manageradd/remove subflowsData sequence (DSN)connection-level orderSubflow SEQper-path TCP orderPacket schedulerwhich subflow sendsReceive reassemblyone ordered streamMiddlebox handlingMP_CAPABLE / fallback to TCPCoupled congestion controlfairness at shared bottleneckOps — path health + scheduler tuning + fallback rate + reinjection statssplitmapschedulemanagenegotiatereassemblecoupleoperateoperate
Multipath TCP: one logical connection carries data-sequence numbers split by a scheduler across TCP subflows on multiple paths, reassembled in order, with coupled congestion control and middlebox fallback.
Advertisement

End-to-end flow

Follow a phone downloading a large file while its owner walks out of a building. The connection opens over Wi-Fi: a normal TCP handshake carrying MP_CAPABLE, and both ends exchange keys — MPTCP is active, with the Wi-Fi flow as the first subflow. The phone's path manager sees a second interface (cellular) with its own address, announces it via ADD_ADDR, and establishes a second subflow over cellular using MP_JOIN, authenticated with the connection keys. Now the single download stream has two paths available.

The scheduler gets to work. Wi-Fi is faster and lower-latency, so it carries most segments; cellular carries some, and the two subflows' bytes are tagged with connection-level DSNs. At the server side each subflow looks like an independent, well-behaved TCP connection — any NAT or firewall between phone and server sees contiguous per-subflow sequence numbers and is content. The receiver reassembles by DSN into one ordered byte stream; the application on the phone just reads bytes, unaware there are two radios involved. Because congestion control is coupled, the two subflows together don't grab more than a fair share where they happen to share a bottleneck upstream.

Now the owner steps outside and Wi-Fi fades. The Wi-Fi subflow's segments start timing out. The scheduler stops assigning new data to it and reinjects the unacknowledged segments onto the cellular subflow, whose congestion window it now grows to absorb the full throughput. From the application's perspective the download never paused — a few segments were delayed and retransmitted on the other path, but the byte stream stayed continuous. When Wi-Fi is gone entirely, the path manager removes that subflow (a REMOVE_ADDR or timeout), and the connection continues on cellular alone. Had the user walked back into range, a new Wi-Fi subflow would rejoin and the scheduler would resume using it. This is the seamless-handover win MPTCP was built for.

Consider the hostile case that shapes the design: one of the paths traverses a middlebox that strips unknown TCP options. The MP_JOIN or the DSS mapping on that subflow doesn't survive; MPTCP detects the broken mapping and falls back — it stops trusting that path for multipath and, in the worst case where even the initial MP_CAPABLE was stripped, the whole connection simply operates as ordinary TCP. The download still completes; MPTCP degraded to TCP rather than failing. And the pathological performance case: if the two paths are wildly asymmetric — cellular at 200ms, Wi-Fi at 20ms — a naive scheduler can cause head-of-line blocking, where fast-path bytes wait in the receive buffer for slow-path bytes to arrive so the stream can be delivered in order. Modern schedulers and adequate receive buffers mitigate this, but it is the effect operators tune against.