β–ΆπŸ—Ί Full Pipeline Diagram
  SCRAPE TARGETS  (exporters, node_exporter, etc.)
        β”‚
        β–Ό
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚           Discovery Manager                 β”‚  discovery/manager.go
  β”‚  (Kubernetes, AWS, Consul, File, DNS, …)    β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                       β”‚  targetgroup.Group
                       β–Ό
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚            Scrape Manager                   β”‚  scrape/manager.go
  β”‚  (one scrapePool per job, relabeling)       β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                       β”‚  HTTP GET /metrics
                       β–Ό
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚             Scrape Loop                     β”‚  scrape/scrape.go
  β”‚  (parse text/protobuf, apply limits)        β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                       β”‚  samples / exemplars / histograms
                       β–Ό
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚           fanoutStorage.Appender            β”‚  storage/fanout.go
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β”‚
       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”
       β–Ό                  β–Ό
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚  Local  β”‚     β”‚       Remote Storage           β”‚
  β”‚  TSDB   β”‚     β”‚  storage/remote/write.go       β”‚
  β”‚         β”‚     β”‚  WAL Watcher β†’ QueueManager    β”‚
  β”‚ β”Œβ”€β”€β”€β”€β”€β” β”‚     β”‚  β†’ HTTP POST remote_write      β”‚
  β”‚ β”‚ WAL β”‚ β”‚     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  β”‚ β””β”€β”€β”¬β”€β”€β”˜ β”‚
  β”‚    β”‚    β”‚
  β”‚ β”Œβ”€β”€β–Όβ”€β”€β” β”‚
  β”‚ β”‚Head β”‚ β”‚   tsdb/head.go
  β”‚ β”‚ +   β”‚ β”‚   (in-memory XOR chunks, memSeries)
  β”‚ β”‚mmap β”‚ β”‚
  β”‚ β””β”€β”€β”¬β”€β”€β”˜ β”‚
  β”‚    β”‚ compaction
  β”‚ β”Œβ”€β”€β–Όβ”€β”€β”€β”€β”€β”€β” β”‚
  β”‚ β”‚ Blocks  β”‚ β”‚   tsdb/block.go
  β”‚ β”‚(on disk)β”‚ β”‚   (index + chunk files)
  β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚
        β–Ό  (Querier)
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚              PromQL Engine                  β”‚  promql/engine.go
  β”‚  (parse AST β†’ select β†’ eval β†’ result)       β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β”‚
       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
       β–Ό                   β–Ό
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ HTTP    β”‚       β”‚   Rule Manager       β”‚  rules/manager.go
  β”‚ API     β”‚       β”‚ (alerting + record.) β”‚
  β”‚/api/v1/ β”‚       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚ firing alerts
                               β–Ό
                        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                        β”‚  Notifier   β”‚  notifier/manager.go
                        β”‚ Alertmanagerβ”‚
                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β–ΆπŸš€ Startup Sequence

All components are wired together in cmd/prometheus/main.go. Initialization order matters β€” storage must be ready before scrapers start.

  1. Config loaded via config.LoadFile(); flags parsed into flagConfig
  2. Local TSDB opened: tsdb.Open() replays WAL, rebuilds Head
  3. remote.NewStorage() β€” remote write queues created per endpoint
  4. storage.NewFanout(local, remote) β€” unified write surface
  5. discovery.NewManager() starts β€” SD providers launch goroutines
  6. scrape.NewManager() starts β€” waits for first config sync from discovery
  7. promql.NewEngine() created with timeout, lookback delta, limits
  8. rules.NewManager() loads rule files, starts evaluation goroutines
  9. Web server starts β€” /api/v1/query, /metrics, /targets, etc.
  10. SIGHUP triggers reloadConfig() β€” all reloader funcs called in order
β–ΆπŸ“¦ Components
β–ΆπŸ”Œ Core Interfaces

All components communicate through a small set of interfaces defined in storage/interface.go.

storage/interface.go β€” key interfaces L82
// Storage combines all sub-interfaces
type Storage interface {
    SampleAndChunkQueryable           // read path
    Appendable                        // write path (deprecated Q2 2026)
    AppendableV2                      // write path (new)
    StartTime() (int64, error)
    Close() error
}

// Appender β€” transactional write interface
type Appender interface {
    Append(ref SeriesRef, l labels.Labels, t int64, v float64) (SeriesRef, error)
    AppendExemplar(ref SeriesRef, l labels.Labels, e exemplar.Exemplar) (SeriesRef, error)
    AppendHistogram(ref SeriesRef, l labels.Labels, t int64, h *histogram.Histogram, ...) (SeriesRef, error)
    Commit() error
    Rollback() error
}

// Querier β€” read interface for a time range
type Querier interface {
    Select(ctx, sortSeries bool, hints *SelectHints, matchers ...*labels.Matcher) SeriesSet
    LabelNames(ctx, hints *LabelHints, matchers ...) ([]string, Warnings, error)
    LabelValues(ctx, name string, hints *LabelHints, matchers ...) ([]string, Warnings, error)
    Close() error
}
SeriesRef is a uint64 opaque handle returned by Append() that can be reused in subsequent calls to skip label lookup β€” key hot-path optimization.
β–ΆπŸ§± Core Data Types
TypePackageDescription
labels.Labels model/labels Sorted key=value pairs identifying a time series
storage.SeriesRef storage uint64 handle for a series within an Appender transaction
chunks.HeadSeriesRef tsdb/chunks uint64 monotonic ID assigned per series in the Head
histogram.Histogram model/histogram Native histogram with bucket counts, sum, count
exemplar.Exemplar model/exemplar High-cardinality trace ID attached to a metric sample
chunkenc.Chunk tsdb/chunkenc Compressed byte slice of (timestamp, value) pairs
β–ΆπŸ”„ Config Reload

Prometheus supports live reload (SIGHUP or /-/reload POST). Each component registers a reloader function.

cmd/prometheus/main.go β€” reloader list ~L1073
reloaders = []reloader{
    {name: "db_storage",       reloader: localStorage.reloader},
    {name: "remote_storage",   reloader: remoteStorage.ApplyConfig},
    {name: "web_handler",      reloader: webHandler.ApplyConfig},
    {name: "query_engine",     reloader: func(cfg *config.Config) error { ... }},
    {name: "scrape",           reloader: scrapeManager.ApplyConfig},
    {name: "scrape_sd",        reloader: discoveryManagerScrape.ApplyConfig},
    {name: "notify",           reloader: notifierManager.ApplyConfig},
    {name: "notify_sd",        reloader: discoveryManagerNotify.ApplyConfig},
    {name: "rules",            reloader: rulesManager.Update},
    {name: "tracing",          reloader: tracingManager.ApplyConfig},
}
Reloaders run sequentially. If any fails, the reload is aborted and the previous config stays active.