Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
4b2bb29
Implement memory limiter prototype
dashpole Aug 7, 2026
49cd9f9
Add unit test for memory limiter recording rule skipping
dashpole Aug 7, 2026
735b247
Fix scrape unregister metric leak and memory limiter edge cases
dashpole Aug 7, 2026
30588f1
memory_limiter: fix actor lifecycle termination and heap free bytes a…
dashpole Aug 7, 2026
766f405
Add automated scenario and integration tests for memory limiter
dashpole Aug 7, 2026
2cca47f
Add adversarial scenarios S6, S7, S8 to memory limiter E2E test suite
dashpole Aug 7, 2026
e52ee45
Add Scenario S9 for dynamic config reload to test suite
dashpole Aug 7, 2026
2d52a91
test: calibrate scenario burst parameters and fix metric parser scheme
dashpole Aug 7, 2026
fd45fa7
Add sustained memory overload and continuous cardinality churn stress…
dashpole Aug 7, 2026
4636846
Add baseline comparison test suite verifying failure modes when memor…
dashpole Aug 7, 2026
747f7df
Add real OS-enforced OOM comparative test verifying baseline crashes …
dashpole Aug 7, 2026
dc92bfa
Add Scenario S10 sustained overload trickle throughput test and calib…
dashpole Aug 7, 2026
af38c37
Calibrate Scenario S10 trickle throughput and OS OOM verification
dashpole Aug 7, 2026
bc8ddd7
Fix vector match assertion in Scenario S10 trickle throughput test
dashpole Aug 7, 2026
16aeb0f
Add 15-minute sustained overload stress test with 50% target load she…
dashpole Aug 7, 2026
f5998dc
Calibrate 15-minute sustained overload test with steady 50% duty-cycl…
dashpole Aug 7, 2026
91a7ca6
Calibrate 15-minute test workload for 45-55% steady state load shedding
dashpole Aug 7, 2026
261250e
Fix Fprintf format argument count in 15-minute sustained test
dashpole Aug 7, 2026
e4d6bdd
Calibrate dynamic churn in 15-minute test for 50% steady-state load s…
dashpole Aug 7, 2026
e90191a
Calibrate 15-minute sustained test for 45-50% steady-state load shedding
dashpole Aug 7, 2026
7f813f3
Set 700 series workload for sustained 50% load shedding
dashpole Aug 7, 2026
2ae6c6d
Calibrate 15-minute test for steady 48-52% load shedding and 100% que…
dashpole Aug 7, 2026
1fd0a38
Calibrate 15-minute test with static 7200-series workload for steady …
dashpole Aug 7, 2026
b4529a7
Calibrate 15-minute test with 3000-series workload for steady 50% loa…
dashpole Aug 7, 2026
d8dfc85
Update assertions for 15-minute sustained overload verification
dashpole Aug 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion cmd/prometheus/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ import (
"github.com/prometheus/prometheus/util/documentcli"
"github.com/prometheus/prometheus/util/features"
"github.com/prometheus/prometheus/util/logging"
"github.com/prometheus/prometheus/util/memorylimiter"
"github.com/prometheus/prometheus/util/notifications"
prom_runtime "github.com/prometheus/prometheus/util/runtime"
"github.com/prometheus/prometheus/web"
Expand Down Expand Up @@ -215,6 +216,7 @@ type flagConfig struct {
enablePerStepStats bool
enableConcurrentRuleEval bool
useStartTimestamps bool
enableMemoryLimiter bool

prometheusURL string
corsRegexString string
Expand Down Expand Up @@ -332,6 +334,9 @@ func (c *flagConfig) setFeatureListOptions(logger *slog.Logger) error {
case "fast-startup":
c.tsdb.EnableFastStartup = true
logger.Info("Experimental fast startup is enabled.")
case "memory-limiter":
c.enableMemoryLimiter = true
logger.Info("Experimental memory limiter is enabled.")
default:
logger.Warn("Unknown option for --enable-feature", "option", o)
}
Expand Down Expand Up @@ -365,6 +370,7 @@ func main() {
collectors.NewGoCollector(
collectors.WithGoCollectorRuntimeMetrics(
collectors.MetricsGC,
collectors.MetricsMemory,
collectors.MetricsScheduler,
collectors.GoRuntimeMetricsRule{Matcher: goregexp.MustCompile(`^/sync/mutex/wait/total:seconds$`)},
),
Expand Down Expand Up @@ -620,7 +626,7 @@ func main() {
a.Flag("scrape.discovery-reload-interval", "Interval used by scrape manager to throttle target groups updates.").
Hidden().Default("5s").SetValue(&cfg.scrape.DiscoveryReloadInterval)

a.Flag("enable-feature", "Comma separated feature names to enable. Valid options: concurrent-rule-eval, created-timestamp-zero-ingestion, delayed-compaction, exemplar-storage, extra-scrape-metrics, memory-snapshot-on-shutdown, metadata-wal-records, old-ui, otlp-deltatocumulative, otlp-native-delta-ingestion, promql-binop-fill-modifiers, promql-delayed-name-removal, promql-duration-expr, promql-experimental-functions, promql-extended-range-selectors, promql-per-step-stats, st-storage, type-and-unit-labels, use-start-timestamps, use-uncached-io, xor2-encoding. See https://prometheus.io/docs/prometheus/latest/feature_flags/ for more details.").
a.Flag("enable-feature", "Comma separated feature names to enable. Valid options: concurrent-rule-eval, created-timestamp-zero-ingestion, delayed-compaction, exemplar-storage, extra-scrape-metrics, memory-limiter, memory-snapshot-on-shutdown, metadata-wal-records, old-ui, otlp-deltatocumulative, otlp-native-delta-ingestion, promql-binop-fill-modifiers, promql-delayed-name-removal, promql-duration-expr, promql-experimental-functions, promql-extended-range-selectors, promql-per-step-stats, st-storage, type-and-unit-labels, use-start-timestamps, use-uncached-io, xor2-encoding. See https://prometheus.io/docs/prometheus/latest/feature_flags/ for more details.").
StringsVar(&cfg.featureList)

a.Flag("agent", "Run Prometheus in 'Agent mode'.").BoolVar(&agentMode)
Expand Down Expand Up @@ -938,6 +944,18 @@ func main() {
os.Exit(1)
}

var memoryLimiter memorylimiter.MemoryLimiter
if cfg.enableMemoryLimiter {
ml, err := memorylimiter.NewManager(&cfgFile.Runtime.MemoryLimiter, logger.With("component", "memory limiter"), prometheus.DefaultRegisterer)
if err != nil {
logger.Error("failed to create memory limiter", "err", err)
os.Exit(1)
}
memoryLimiter = ml
cfg.scrape.MemoryLimiter = ml
cfg.web.MemoryLimiter = ml
}

scrapeManager, err := scrape.NewManager(
&cfg.scrape,
logger.With("component", "scrape manager"),
Expand Down Expand Up @@ -1000,6 +1018,7 @@ func main() {
},
FeatureRegistry: features.DefaultRegistry,
Parser: promqlParser,
MemoryLimiter: memoryLimiter,
})
}

Expand Down Expand Up @@ -1164,6 +1183,14 @@ func main() {
}, {
name: "tracing",
reloader: tracingManager.ApplyConfig,
}, {
name: "memory_limiter",
reloader: func(cfg *config.Config) error {
if memoryLimiter != nil {
return memoryLimiter.ApplyConfig(&cfg.Runtime.MemoryLimiter)
}
return nil
},
},
}

Expand Down Expand Up @@ -1257,6 +1284,21 @@ func main() {
},
)
}
if memoryLimiter != nil {
ctxML, cancelML := context.WithCancel(context.Background())
g.Add(
func() error {
memoryLimiter.Start(ctxML)
<-ctxML.Done()
return nil
},
func(error) {
logger.Info("Stopping memory limiter...")
cancelML()
memoryLimiter.Stop()
},
)
}
if !agentMode {
// Rule manager.
g.Add(
Expand Down
Loading
Loading