feat(delta): implement delta transmission over time windows and series - #65
Merged
Merged
Conversation
…smission commit Points to 307870c9fb which adds delta transmission for CMS, CS, HLL, DDSketch, and KLL processors (Phases 3-7). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…lta-transmission commit" This reverts commit 0a57a6f.
…h, KLL processors Copies updated processor files into opentelemetry-collector-contrib-patch/ per the repo's patch-overlay workflow (backup_otel_collector_contrib_patches.sh). Changes in patch overlay: - processor/countminsketchprocessor: DeltaTransmission + DeltaThreshold config, snapshot map + ComputeDelta/ApplyDelta flush path, go.mod local sketchlib-go replace - processor/countsketchprocessor: same delta mode + fix Insert/Estimate API for new sketchlib-go version - processor/countminsketchmergeprocessor: NEW — receiver-side CMS accumulator (decodes proto_delta/proto_full, ApplyDelta/Merge per aggregation_key) - processor/countsketchmergeprocessor: NEW — receiver-side CS accumulator - processor/hllprocessor: DeltaTransmission config, register delta via ComputeRegisterDelta, hll.encoding attribute, API fixes for new sketchlib-go - processor/ddsketchprocessor: DeltaTransmission + DeltaThreshold config, sparse bucket delta via sketchpb.DDSketch Store diffing - processor/kllprocessor: delta_transmission guard in Validate() — KLL is not additively mergeable Also adds docs/delta-transmission-design.md (the design spec for this feature). Corresponding sketchlib-go changes: PR #43 (proto delta messages + ComputeDelta/ApplyDelta for CMS/CS/HLL/DDSketch) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ion unification - Restore AggregateBy/LabelMatchers/LabelMatcher in CMS and CS configs (regressed in d3ef3a2 which used old GroupBy naming) - Rename WindowInterval (CMS) and WindowSize (CS) to WindowDuration to match HLL/DDSketch/KLL naming - Upgrade CS processor from global row/col sketch to per-partition windowSketch architecture (supports all 3 modes: batch, window, matrix) - Add LabelMatchers filtering to CS ingestMetric - CMS processor: preserve AggregateBy/seriesKey/seriesAttrs/matchesMatchers logic while adding delta transmission snapshot tracking - All tests pass for both processors Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… cmd yamls Update countminsketchcol and countsketchcol config.yaml files to use unified window_duration key. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Submodule opentelemetry-go must stay at the upstream commit (4575a977). All local SDK changes live in opentelemetry-go-patch/. Add backup_opentelemetry_go_patches.sh and restore_opentelemetry_go_patches.sh (mirroring the pattern used for collector/contrib/proto), and wire them into the umbrella backup_otel_patches.sh / restore_otel_patches.sh. Workflow: ./restore_opentelemetry_go_patches.sh — copy patches → submodule (enables compilation) ./backup_opentelemetry_go_patches.sh — copy submodule diffs → patch folder (saves work) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ch exports Phase 14: SDK-to-Collector delta transmission. Add sparse delta encoding to the cumulative() export path of the three SDK sketch aggregators so the application sends only changed cells/registers to the collector instead of the full sketch every export cycle. Changes: - metricdata/data.go: add HLLSketchEncodingDelta, CountMinSketchEncodingDelta, CountSketchEncodingDelta encoding constants - aggregation.go: add DeltaTransmission bool + DeltaThreshold float64 to AggregationCountSketch, AggregationCountMinSketch; add DeltaTransmission to AggregationHLLSketch (no threshold — HLL registers are monotone) - pipeline.go: thread new fields through to Builder method calls - aggregate.go: update Builder.CountSketch/CountMinSketch/HLLSketch signatures; add Builder.Noop() for the no-transmit path - hllsketch.go: add snapshots map + payloadFor helper; delta encoding in cumulative() via hll.ComputeRegisterDelta; eviction cleans snapshots - countminsketch.go: add snapshots map + payloadFor helper; delta encoding in cumulative() via cms.ComputeDelta; cloneCMSketch helper - countsketch.go: add snapshots map + payloadFor helper; delta encoding in cumulative() via countsketch.ComputeDelta; cloneCSSketch helper - sdk/metric/go.mod: add replace directive to use local sketchlib-go (add-delta-transmission branch) with ComputeDelta/ComputeRegisterDelta Design doc: add §14 SDK-to-Collector Delta Transmission with architecture, config table, encoding wire values, implementation file list, snapshot lifecycle, and interaction with collector-side delta (§1-7). All sdk/metric tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ission to ddsketch/hll processors - ddsketchprocessor/config.go: restore LabelMatcher struct, AggregateBy, LabelMatchers fields from main; add sort.Strings(AggregateBy) in Validate() - ddsketchprocessor/processor.go: restore matchesMatchers/seriesKey/seriesAttrs; add delta transmission logic in buildMergedSketchMetric; add computeDDSketchDelta/storeDelta/storeToMap helpers - ddsketchprocessor/processor_test.go: restore TestDDAggregateByCollapsesSeries, TestDDLabelMatchersFilterGauge, TestDDAggregateByWindowModeDDSketchInput - hllprocessor/config.go: restore LabelMatcher struct, AggregateBy, LabelMatchers fields from main; keep DeltaTransmission field added in this branch - hllprocessor/processor.go: restore matchesMatchers/seriesKey/seriesAttrs; fix HLL API (InsertValue/EstimateCardinality); add delta transmission logic + appendHLLDeltaDataPoint/cloneHLL helpers - hllprocessor/processor_test.go: restore TestHLLAggregateByCollapsesSeries, TestHLLLabelMatchersFilter - kllprocessor/config.go: restore LabelMatcher struct, AggregateBy, LabelMatchers, sort.Strings; keep DeltaTransmission with validation error - kllprocessor/processor.go: restore matchesMatchers/seriesKey/seriesAttrs - kllprocessor/processor_test.go: restore TestAggregateByCollapsesSeries, TestLabelMatchersFilterGauge, TestAggregateByWithLabelMatchersWindowMode Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Mirror the pattern already implemented for HLL, CountMin, and CountSketch: - metricdata/data.go: add DDSketchEncodingProtoDelta constant - aggregation.go: add DeltaTransmission bool + DeltaThreshold uint64 to AggregationDDSketch - pipeline.go: pass new fields through to Builder.DDSketch() - aggregate/aggregate.go: update Builder.DDSketch() signature - aggregate/ddsketch.go: add snapshots map + snapshotsMu; implement payloadFor() that computes sparse delta (ddSketchDeltaPayload/ddStoreDelta/ddStoreToMap) in cumulative() path; exportDataPoint now accepts pre-computed payload+encoding; snapshot evicted alongside series to prevent memory leak - aggregate/ddsketch_test.go: update existing test calls to new signature (deltaTransmission=false, threshold=0) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…design ## Wire format (proto + pdata) - opentelemetry-proto: add DDSKETCH_ENCODING_PROTO_DELTA=2, HLL_SKETCH_ENCODING_DELTA=2, COUNT_MIN_SKETCH_ENCODING_DELTA=2, COUNT_SKETCH_ENCODING_DELTA=2 to encoding enums - opentelemetry-collector pdata/internal: add delta enum constants to all 4 generated encoding enum files - opentelemetry-collector pdata/pmetric: add DDSketchEncodingProtoDelta, HLLSketchEncodingDelta, CountMinSketchEncodingDelta, CountSketchEncodingDelta exported constants with String() support ## Collector inbound delta reconstruction - hllprocessor: add inboundSnapshots map + inboundMergeHLL helper; applies hll.ApplyRegisterDelta for HLLSketchEncodingDelta payloads in processBatch and accumulateHLLSketchMetric; stores full snapshot on HLLSketchEncodingBinary - ddsketchprocessor: add inboundSnapshots map; convert decodeDDSketchDataPoint to method with seriesKey; add applyDDSketchDelta/applyDDStore helpers; reconstructs full sketch from proto delta before merging; returns nil,nil when no snapshot yet - countminsketchprocessor: add inboundSnapshots map + inboundDecodeCMS helper; applies cms.ApplyDelta for CountMinSketchEncodingDelta in ingestMetric ## Design doc - §14: update scope to include DDSketch; expand §14.4 encoding table (SDK + proto); expand §14.5 with full implementation file table including inbound reconstruction; update §14.7 to describe two-layer snapshot model (inbound + outbound independent) - §16 (new): Controller-Driven Sketch Sizing and Delta Window Configuration — sizing rules for CMS/CS/HLL/DDSketch, target_window_duration derivation, joint co-optimization loop, new AgentCollectorConfig fields, monitor feedback loop Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…aggregated CS - Add inboundSnapshots map + inboundMu to countSketchProcessor struct - inboundDecodeCS: handles CountSketchEncodingGob (full) and CountSketchEncodingDelta; applies countsketch.ApplyDelta to reconstruct current full sketch from sparse delta; returns nil,nil when delta arrives before any full snapshot - mergeWindowCS: merges reconstructed CS into the running window sketch via Merge(); creates window sketch (via newConfiguredCountSketch) if not yet present - MetricTypeCountSketch case in ingestMetric: routes sketch payload through inboundDecodeCS + mergeWindowCS; falls back to raw sample (1.0) only when Sketch() is empty (backward compat with count-only data points) - Update §14.5 design doc: countsketchprocessor now listed with full inbound reconstruction support alongside hll/ddsketch/cms processors Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- countsketchprocessor README: window_size -> window_duration, add mode/ drop_original/aggregate_by/label_matchers fields that exist on main - countmin_bench.sh: window_interval -> window_duration in comment - config.yaml: remove stale "# NEW:" annotation on window_duration Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove `replace github.com/ProjectASAP/sketchlib-go => /tmp/sketchlib-go` from all go.mod files and update to the resolved pseudo-version v0.0.0-20260320220729-3ba826ceb054 from the add-delta-transmission branch. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Code fix: - opentelemetry-go-patch/sdk/metric/go.mod: remove local /tmp/sketchlib-go replace directive; update to GitHub pseudo-version v0.0.0-20260320220729-3ba826ceb054 Doc fixes (delta-transmission-design.md): - §6 Phase 3/4: sync.RWMutex → sync.Mutex (matches actual snapshotsMu/accMu types) - §6 Phase 3: WindowSize → WindowDuration (matches actual config field name) - §12 table: WindowSize → WindowDuration; add AggregateBy, LabelMatchers to current-state column for cms/cs processors - §13.2: window_size → window_duration in fill rate formula - §13.3: window_size: 30s → window_duration: 30s in YAML example - §14.3: add AggregationDDSketch DeltaTransmission/DeltaThreshold rows (DDSketch is implemented in the SDK aggregator) - §14.5: sdk/metric/go.mod entry updated to reflect GitHub pseudo-version instead of local path replace Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… types Rename HLL_SKETCH_ENCODING_BINARY→PROTO, COUNT_MIN_SKETCH_ENCODING_GOB→PROTO, COUNT_SKETCH_ENCODING_GOB→PROTO, KLL_SKETCH_ENCODING_GOB→PROTO in metrics.proto, pdata/internal generated enum files, and pdata/pmetric encoding files. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… bump sketchlib-go - Replace gob encoding with SerializeProtoBytes in countminsketch aggregator - Replace SerializeToBytes with SerializeProtoBytes in countsketch, hll, kll aggregators - Update cloneXxx helpers to use proto round-trip - Rename encoding constants to Proto variants in metricdata/data.go - Bump sketchlib-go to v0.0.0-20260321021603-cddd774cb224 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ocessors; bump sketchlib-go - countminsketchprocessor: serializeCMS/deserializeCMS/cloneCMS use proto methods - countsketchprocessor: SerializeProtoBytes, DeserializeCountSketchFromProtoBytes - hllprocessor: SerializeProtoBytes, DeserializeHyperLogLogFromProtoBytes - kllprocessor: SerializeProtoBytes, DeserializeKLLSketchFromProtoBytes - countminsketchmergeprocessor: DeserializeCountMinSketchFromProtoBytes - countsketchmergeprocessor: DeserializeCountSketchFromProtoBytes - Bump all processor go.mod to sketchlib-go v0.0.0-20260321021603-cddd774cb224 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…aggregators sketchlib-go ecebc36: delta.go = pure algorithm on sketch structs (no proto); delta_codec.go = bytes <-> proto <-> sketch struct in one pass. Callers now explicitly: ComputeDelta(snap, current) -> *Delta -> SerializeDelta -> []byte (send) DeserializeDelta([]byte) -> *Delta -> ApplyDelta(target) (recv) Bump sketchlib-go to v0.0.0-20260321023259-ecebc36fb5aa across all go.mod files. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ump sketchlib-go Adds delta_transmission_test.go to countminsketchprocessor (5 tests), countsketchprocessor (6 tests), and hllprocessor (5 tests). All 16 pass. Coverage per processor: - FirstWindowSendsFullSketch: no prior snapshot → proto_full encoding - SubsequentWindowsSendDelta: snapshot exists → proto_delta encoding - RoundTrip: ApplyDelta(clone(snap), delta) == independent reference sketch - MultipleWindowsConvergence: 5 windows, receiver reconstructs correct state each time - DisabledAlwaysSendsFullSketch: DeltaTransmission=false → always proto_full - PartitionKeyIsolation (CS only): two services independently transition full→delta - MaxSemanticsIdempotent (HLL only): applying delta twice == applying once Also bumps sketchlib-go to v0.0.0-20260321024028-d20a9f9151b5 (threshold bug fixes + delta tests) in all go.mod files. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SieDeta
pushed a commit
that referenced
this pull request
Apr 17, 2026
…me-windows feat(delta): implement delta transmission over time windows
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements the delta transmission design from
docs/delta-transmission-design.md.sketchlib-go (PR #43, stacked on
add-octosketch)proto/sketchlib.proto—SketchDeltaEnvelope,CountMinDelta,CountSketchDelta,HLLDelta,DDSketchDeltaand their cell/register types. Regeneratedsketchlib.pb.go.ComputeDelta/ApplyDeltain each sketch package:CountMinSketch/delta.go— sparse cell diff with threshold; L1/L2 always includedCountSketch/delta.go— signed cell diff; TopK retransmitted in fullHLL/delta.go— increased registers only (max semantics, zero threshold)DDSketch/delta.go— bucket count diff >= threshold; sum/min/max always transmittedDataCollector (this PR)
countminsketchprocessorandcountsketchprocessordelta_transmission: bool,delta_threshold: float64ComputeDeltaon flush;encoding="proto_delta"/"proto_full"attributecountminsketchmergeprocessor— reconstructs CMS from proto_full/proto_delta streamcountsketchmergeprocessor— same for CountSketchhllprocessordelta_transmission: boolComputeRegisterDelta;hll.encodingattribute on data pointsddsketchprocessordelta_transmission: bool,delta_threshold: uint64kllprocessordelta_transmission: true→Validate()returns error (KLL is not additively mergeable)Wire protocol
Data points carry two new attributes when
delta_transmission=true:encoding: "proto_delta"or"proto_full"sketch_payload: bytes(proto-marshalled delta or full sketch)First window per partition always sends
proto_full. Subsequent windows sendproto_deltaif snapshot exists.Test plan
ComputeDelta(snapshot, current, threshold)→ApplyDeltaroundtrip produces same estimatesValidate()rejectsdelta_transmission: trueRelated
🤖 Generated with Claude Code