**Approach (brief)** I’d treat mobile as the trace root for user-initiated flows: generate a stable trace-id per action, propagate it through requests, and stitch server spans back to that mobile root even when uploads are delayed.**Correlation ID propagation** - Use W3C Trace Context (traceparent) + an app-level correlation-id for user-visible actions. - Generate at action start on the device (UUID/v4 or 128-bit trace id). Attach as headers to every outbound request and background job: traceparent, tracestate, X-Correlation-ID. - Example (pseudo): kotlin
// Kotlin Android example
val traceId = UUID.randomUUID().toString()
val traceHeader = "00-$traceId-0000000000000001-01"
request.addHeader("traceparent", traceHeader)
request.addHeader("x-correlation-id", traceId)
**Client & server sampling strategies** - Client-side: lightweight deterministic sampling for high-volume noise (e.g., 1% for background heartbeats) and event-based forced-sampling for important flows (payments, errors). Store sampling decision with trace-id so servers honor it. - Server-side: honor client sampling header; implement adaptive tail-sampling (sample whole traces if any service records error/high latency). Use probabilistic + rate-limited high-priority sampling.**Privacy considerations** - Never include PII (usernames, emails, precise GPS) in trace payloads or headers. Hash/ID-encode any identifiers, and provide opt-out. Encrypt stored telemetry and respect platform privacy APIs (Android’s privacy sandbox, iOS consent). Truncate or bucket sensitive metrics (e.g., coarse geo by region).**Low-overhead client SDK design** - Minimal sync work on main thread; use batching, periodic uploads, exponential backoff, and small in-memory ring buffer with persistent fallback (SQLite/files) sized for few KBs. Keep serializers compact (binary/protobuf). Expose simple API: startSpan/finishSpan, attachError, setSamplingDecision. Use platform background transfer APIs (WorkManager, NSURLSession background) to reduce battery/network impact.**Reconstructing traces with intermittent connectivity** - Store breadcrumbs/spans locally with trace-id and parent ids. On reconnection, upload batches preserving timestamps. Servers should accept out-of-order spans and reconstitute traces via trace-id; use a reassembly buffer and eventually consistent trace view. Implement TTL and deduplication to avoid replaying. If full server-side spans missing, link server traces to mobile trace via correlation-id and present partial end-to-end causal chain in UI.**Trade-offs / practical notes** - W3C interop vs simple header choice; privacy vs observability balance; favor sampling that preserves error/latency signals. Keep SDK tiny and configurable per-app privacy/policy.