Why upstream Linux

linux-tcp-cc deliberately optimizes for upstream Linux TCP fidelity before minimum footprint.

The project is not trying to recreate BBR, CUBIC, Linux delivery-rate sampling, TCP recovery, or fq pacing in a smaller custom stack. It moves ownership of the public TCP socket into a hosted upstream Linux networking stack so those behaviors remain owned by Linux itself.

The design choice

A compact userspace TCP stack is possible. The question is what the project wants to preserve.

linux-tcp-cc chooses this boundary:

public TCP socket
    ↓
hosted upstream Linux
    ↓
Linux BBR / CUBIC
Linux rate sampling
Linux recovery
Linux fq pacing
    ↓
byte-stream bridge
    ↓
ordinary 127.0.0.1 backend

Project-specific code stays around the hosting boundary: lifecycle, TUN, host packet steering, control, memory return, and the backend bridge.

The main repository treats important upstream networking sources as protected behavior during routine maintenance, including Linux BBR, rate sampling, recovery, and fq.

Why this matters

Implementing an algorithm named “BBR” is not automatically the same thing as running Linux BBR.

The controller consumes transport observations and interacts with pacing, recovery, socket state, and delivery-rate accounting. A smaller TCP stack can be correct and useful, but it owns more of those semantics itself.

tcpcc instead makes Linux the reference implementation by construction.

That is the main reason to choose this project over a smaller userspace TCP stack.

The cost

Hosting Linux is heavier than embedding a purpose-built TCP implementation.

tcpcc therefore works to reduce that cost without moving TCP semantics out of Linux:

  • demand-backed hosted memory;
  • reclaim of pages proven free;
  • reclaim of discardable init mappings;
  • tickless idle;
  • budgeted/coalesced packet work;
  • event-driven bridge ownership;
  • no per-connection forwarding thread model.

This makes the hosted-kernel approach practical on constrained machines, but it does not turn it into the minimum-memory option.

Relation to tcp-shift

The same maintainer develops tcp-shift, which intentionally explores the opposite tradeoff.

linux-tcp-cc tcp-shift
Primary goal upstream Linux TCP fidelity small userspace TCP endpoint
TCP implementation hosted upstream Linux lwIP
Congestion-control boundary Linux owns BBR/CUBIC semantics explicit project controller integration
Recovery direction Linux recovery RFC-oriented transport work such as RACK-TLP
Fixed footprint larger substantially smaller
Best fit “I want Linux TCP behavior” “I want a compact userspace endpoint”

tcp-shift is not a replacement for linux-tcp-cc, and linux-tcp-cc is not intended to replace tcp-shift. They exist to explore different engineering boundaries.

What the fidelity claim does not mean

The hosted stack runs behind TUN, DNAT/conntrack, a userspace execution boundary, and a configured guest-memory arena. Timing and performance can therefore differ from bare-metal Linux.

The precise claim is about implementation ownership:

  • the public socket is a Linux socket;
  • BBR/CUBIC are the Linux implementations;
  • Linux owns the associated recovery/rate-sampling/pacing semantics.

Performance still has to be measured for the deployment and workload in question.

For the canonical design rationale, see docs/upstream-linux-fidelity.md.