Full-fidelity tracing on a busy service is a considerable volume of data and a considerable bill, and almost all of it describes requests that were fine.
// head-based: decide at the start, propagate the decision
$sampled = random_int(1, 100) <= 1; // 1%
// tail-based: buffer, then keep what is interesting
// every trace with an error
// every trace slower than the p99
// 1% of the rest
//
// tail-based needs a collector that can hold a whole trace.
Head-based sampling is simple and throws away the slow requests along with everything else, which is exactly backwards — the interesting traces are the rare ones. Tail-based keeps what matters and requires a collector holding every span until the trace completes, which is real infrastructure. Propagating the sampling decision is what keeps a trace whole; a service that decides independently produces traces with holes in them.