netdata/netdata
The fastest path to AI-powered full stack observability, even for lean teams.
12 hidden assumptions · 5-stage pipeline · 9 components
Like any codebase, this dashboard makes assumptions it never checks — most are routine. The ones worth your attention are below.
Collects, stores, and streams real-time system metrics with low overhead
Metrics flow from system sources through specialized collectors into journal storage, then stream to web clients or external systems. Collectors like proc.plugin read /proc files, python.d.plugin executes Python scripts, and go.d.plugin runs Go modules — all feeding data into RRDSets (circular buffers) that maintain recent values. The data gets written to journal files using memory-mapped I/O with hash indexing for efficient queries. Simultaneously, the web server serves real-time data to dashboards via API calls, while streaming components forward metrics to parent nodes or cloud services.
Under the hood, the system uses 4 feedback loops, 4 data pools, 5 control points to manage its runtime behavior.
A 9-component dashboard. 3464 files analyzed. Data flows through 5 distinct pipeline stages.
Hidden Assumptions
Most of what this code assumes is routine. These 3 are the ones most likely to cause trouble here. The rest are minor; they're under "Show everything".
If machine-id contains non-hex characters, has wrong length, or is missing, journal files cannot be created/opened - causing complete monitoring system failure with cryptic 'UuidSerde' errors that don't indicate the root cause
In container environments without proper volume mounts or with restricted permissions, the fallback to /host/etc/machine-id fails silently or with permission errors, leaving no way to access the machine ID
If called from C code with non-null-terminated strings or freed memory, the CStr::from_ptr() call reads past allocated memory, potentially causing segfaults or reading garbage data into the ID structure
Show everything (9 more)
System page size is always exactly 4096 bytes across all target platforms and architectures
If this fails: On systems with different page sizes (like some ARM64 with 64KB pages), memory mappings will be misaligned, causing performance degradation or mapping failures when the OS requires page-aligned offsets
src/crates/jf/window_manager/src/lib.rs:PAGE_SIZE
GUID format dashes appear at exactly positions 8, 13, 18, and 23, and non-GUID format contains no dashes at all
If this fails: Malformed UUIDs with dashes in wrong positions return -1 error code, but the calling C code may not handle this gracefully, potentially using uninitialized RsdId128 data in subsequent operations
src/crates/jf/journal_reader_ffi/src/lib.rs:rsd_id128_from_string
The filesystem has sufficient space and the process has permission to extend files via set_len() when mapping regions beyond current file size
If this fails: When journal files need to grow but disk is full or filesystem is read-only, set_len() fails and the entire memory mapping operation aborts, stopping metric collection with no graceful degradation
src/crates/jf/window_manager/src/lib.rs:MemoryMapMut::create
Memory mapping offsets and sizes fit within usize limits on the target platform (offset: u64 cast to usize for len parameter)
If this fails: On 32-bit systems or when mapping very large journal files (>4GB), the size cast from u64 to usize silently truncates, creating mappings smaller than requested and causing out-of-bounds access when reading data
src/crates/jf/window_manager/src/lib.rs:MmapOptions
Callers always validate position and size parameters against window bounds before calling get_slice() - the debug_assert provides no protection in release builds
If this fails: In production builds, invalid position/size parameters cause get_slice to return memory outside the mapped region, leading to potential segfaults or reading garbage data without any error indication
src/crates/jf/window_manager/src/lib.rs:Window::get_slice
The window's memory mapping remains valid and hasn't been unmapped by another thread between the bounds check and actual memory access
If this fails: In multi-threaded scenarios, a window could be unmapped after contains_range() returns true but before get_slice() accesses the memory, resulting in segfaults from accessing unmapped memory
src/crates/jf/window_manager/src/lib.rs:Window::contains_range
Input bytes represent ASCII characters in the range 0-127, not UTF-8 multibyte sequences
If this fails: When processing UTF-8 strings containing non-ASCII characters that happen to have byte values in hex ranges, unhexchar processes individual bytes rather than characters, producing incorrect hex decoding results
src/crates/jf/journal_reader_ffi/src/lib.rs:unhexchar
The target_os configuration correctly identifies Linux systems, and non-Linux systems don't call this function
If this fails: If compiled for Linux but running on a different OS, or if the cfg attribute fails to properly exclude the function, attempts to read /etc/machine-id will fail on systems that don't have this file
src/crates/jf/journal_file/src/file.rs:load_machine_id
The File reference remains valid and the underlying file descriptor hasn't been closed during the memory mapping operation
If this fails: If the file is closed by another thread or process during mapping, the unsafe mmap operations may succeed but create invalid mappings, leading to segfaults or data corruption when accessing the mapped memory
src/crates/jf/window_manager/src/lib.rs:unsafe MmapOptions
Open the standalone hidden-assumptions report for netdata →
How Data Flows Through the System
Metrics flow from system sources through specialized collectors into journal storage, then stream to web clients or external systems. Collectors like proc.plugin read /proc files, python.d.plugin executes Python scripts, and go.d.plugin runs Go modules — all feeding data into RRDSets (circular buffers) that maintain recent values. The data gets written to journal files using memory-mapped I/O with hash indexing for efficient queries. Simultaneously, the web server serves real-time data to dashboards via API calls, while streaming components forward metrics to parent nodes or cloud services.
- System metric collection — Collectors like proc.plugin scan /proc filesystem files, python.d.plugin executes configured Python modules, and go.d.plugin runs Go-based collectors — each gathering specific metrics (CPU usage, memory stats, network counters, application metrics) on scheduled intervals [System files and APIs → MetricPoint]
- Metric processing and storage — The RRDEngine receives MetricPoint data, stores it in RRDSet circular buffers for immediate access, and writes to journal files using JournalFile component with hash-based indexing — all while maintaining data compression and retention policies [MetricPoint → JournalEntry]
- Real-time web serving — WebServer handles incoming HTTP requests from dashboards, queries the RRDEngine for time-series data within specified ranges, and returns JSON or CSV formatted responses — with WebSocket connections providing live metric streaming [WebRequest → HTTP responses with metric data]
- External data streaming — StreamingSender component packages metrics into StreamingMessage format with compression, establishes TCP connections to parent nodes or cloud endpoints, and transmits data with retry logic and acknowledgment handling [MetricPoint → StreamingMessage]
- Health monitoring and alerting — HealthEngine continuously evaluates incoming metrics against configured thresholds using alarm expressions, maintains alert state machines (OK/WARNING/CRITICAL), and triggers notification workflows when conditions change [MetricPoint → Alert states]
Data Models
The data structures that flow between stages — the contracts that hold the system together.
src/database/rrdset.cstruct with timestamp: time_t, value: NETDATA_DOUBLE, flags: uint8_t indicating data quality and collection state
Created by collectors every collection interval, stored in circular buffers, and streamed to clients on demand
src/crates/jf/journal_file/src/object.rszerocopy struct with header: ObjectHeader (magic, type, size), realtime: u64, monotonic: u64, xor_hash: u64, plus variable-length field data
Written by journal writer with field metadata, stored in memory-mapped files with hash indexing, and read through filtered cursors
src/database/rrdset.hstruct containing chart metadata: id, name, family, context, dimensions array, update_every interval, and circular buffer for recent values
Created when first metric arrives, continuously updated by collectors, and queried by web API with time range filtering
src/streaming/sender.cbinary protocol with header (message_type, compression_flags, data_length) followed by serialized metric data or metadata commands
Constructed from collected metrics, compressed if configured, transmitted over TCP connections with acknowledgment tracking
src/web/api/web_api_v1.cHTTP request structure with method, path, query parameters (chart, after, before, points, format), headers, and parsed authentication context
Parsed from incoming HTTP connections, routed to appropriate handlers based on path, and responded to with JSON or CSV formatted data
System Behavior
How the system operates at runtime — where data accumulates, what loops, what waits, and what controls what.
Data Pools
Memory-mapped journal files that accumulate time-series metric data with hash-based indexing, allowing efficient range queries and filtering without loading entire files into memory
Fixed-size circular buffers within RRDSet structures that maintain recent metric values for immediate access, automatically overwriting oldest data when capacity is reached
Temporary buffers that accumulate metrics awaiting transmission to parent nodes, with overflow protection and compression staging areas
Active HTTP and WebSocket connections maintained in memory with session state, authentication context, and streaming subscriptions
Feedback Loops
- Collection Scheduling Loop (polling, reinforcing) — Trigger: Timer expiration based on update_every configuration. Action: CollectorManager executes all registered collectors, processes their output, and schedules next collection cycle. Exit: System shutdown or collector failure threshold exceeded.
- Streaming Retry Loop (retry, balancing) — Trigger: Connection failure or acknowledgment timeout. Action: StreamingSender attempts reconnection with exponential backoff, buffers pending data, and retries transmission. Exit: Successful connection established or maximum retry count reached.
- Memory-mapped Window Management (cache-invalidation, balancing) — Trigger: Window cache miss or memory pressure. Action: WindowManager unmaps least recently used memory windows and creates new mappings for requested file regions. Exit: Required data window successfully mapped.
- Health Alert Loop (polling, reinforcing) — Trigger: New metric data arrival. Action: HealthEngine evaluates all configured alarm expressions against current values and updates alert states. Exit: All evaluations complete.
Delays
- Collection Intervals (scheduled-job, ~1-60 seconds configurable per collector) — Determines metric resolution and system resource usage — shorter intervals provide finer granularity but consume more CPU and memory
- Journal Write Batching (batch-window, ~Variable based on buffer fill or timeout) — Metrics accumulate in memory before being flushed to disk, balancing write performance against potential data loss on system crashes
- Streaming Buffer Flush (rate-limit, ~Network-dependent with configurable thresholds) — Data queues in local buffers during network congestion or parent node unavailability, affecting real-time replication
- Memory Map Window Creation (async-processing, ~Microseconds for page fault handling) — First access to unmapped journal regions triggers memory mapping setup, causing brief latency spikes in data queries
Control Points
- Collection Update Frequency (hyperparameter) — Controls: How often collectors gather metrics — affects data granularity, resource usage, and storage requirements. Default: 1 second default
- Memory Usage Limits (threshold) — Controls: Maximum memory allocated for metric storage before forcing disk writes and cache eviction. Default: Dynamic based on available system RAM
- Streaming Destination (env-var) — Controls: Whether to send metrics to cloud services, parent nodes, or disable streaming entirely. Default: Configurable per installation
- Web Server Thread Pool Size (architecture-switch) — Controls: Number of concurrent HTTP connections supported and response latency under load. Default: Auto-scaled based on system cores
- Journal Compression (feature-flag) — Controls: Whether to compress journal entries for storage efficiency at cost of CPU usage. Default: Enabled by default
Technology Stack
Implements the high-performance journal file storage system with memory-mapped I/O, zero-copy serialization, and safe concurrency primitives
Core daemon implementation, system-level collectors, web server, and integration with Linux kernel interfaces for metric gathering
Extensible collector scripts for application-specific metrics, database monitoring, and third-party service integration
Modern collector implementation with concurrent metric gathering, structured configuration, and cloud service integrations
Efficient file I/O for journal storage with operating system page cache integration and demand-paged memory access
Rust crate enabling direct casting of memory-mapped regions to structured data without serialization overhead
Cross-platform build system managing complex multi-language compilation with dependency resolution and feature detection
Key Components
- JournalFile (store) — Memory-mapped journal file reader/writer that provides efficient access to time-series data using a window-based mapping strategy to avoid loading entire files into memory
src/crates/jf/journal_file/src/file.rs - WindowManager (allocator) — Manages memory-mapped file windows by creating page-aligned memory maps on demand, reusing existing windows when possible, and handling file growth for write operations
src/crates/jf/window_manager/src/lib.rs - RRDEngine (processor) — High-performance time-series database engine that manages metric storage using memory pages, compression, and disk persistence with configurable retention policies
src/database/engine/rrdengine.c - CollectorManager (orchestrator) — Coordinates the execution of metric collectors by managing plugin processes, scheduling collection intervals, and handling collector failures with restart logic
src/daemon/buildinfo.c - StreamingSender (dispatcher) — Transmits collected metrics to parent nodes or cloud services using compressed binary protocol with connection management, retry logic, and bandwidth throttling
src/streaming/sender.c - WebServer (gateway) — HTTP server that serves the dashboard interface and API endpoints, handling concurrent connections with thread pool management and request routing
src/web/server/web_server.c - LocalSockets (adapter) — System interface that reads network socket information from /proc filesystem to collect listening ports, established connections, and process associations
src/libnetdata/local-sockets/local-sockets.h - HealthEngine (monitor) — Evaluates metric values against configured alarm thresholds, maintains alert state transitions, and triggers notifications when conditions are met
src/health/health.c - MLEngine (processor) — Machine learning component that analyzes metric patterns to detect anomalies using trained models, providing predictive insights and automated outlier detection
src/ml/ml.c
Explore the interactive analysis
See the full architecture map, data flow, and code patterns visualization.
Analyze on CodeSeaRelated Dashboard Repositories
Frequently Asked Questions
What is netdata used for?
Collects, stores, and streams real-time system metrics with low overhead netdata/netdata is a 9-component dashboard written in C. Data flows through 5 distinct pipeline stages. The codebase contains 3464 files.
How is netdata architected?
netdata is organized into 4 architecture layers: Collection Layer, Storage Engine, Streaming & Export, Core Daemon. Data flows through 5 distinct pipeline stages. This layered structure keeps concerns separated and modules independent.
How does data flow through netdata?
Data moves through 5 stages: System metric collection → Metric processing and storage → Real-time web serving → External data streaming → Health monitoring and alerting. Metrics flow from system sources through specialized collectors into journal storage, then stream to web clients or external systems. Collectors like proc.plugin read /proc files, python.d.plugin executes Python scripts, and go.d.plugin runs Go modules — all feeding data into RRDSets (circular buffers) that maintain recent values. The data gets written to journal files using memory-mapped I/O with hash indexing for efficient queries. Simultaneously, the web server serves real-time data to dashboards via API calls, while streaming components forward metrics to parent nodes or cloud services. This pipeline design reflects a complex multi-stage processing system.
What technologies does netdata use?
The core stack includes Rust (Implements the high-performance journal file storage system with memory-mapped I/O, zero-copy serialization, and safe concurrency primitives), C (Core daemon implementation, system-level collectors, web server, and integration with Linux kernel interfaces for metric gathering), Python (Extensible collector scripts for application-specific metrics, database monitoring, and third-party service integration), Go (Modern collector implementation with concurrent metric gathering, structured configuration, and cloud service integrations), Memory Mapping (mmap) (Efficient file I/O for journal storage with operating system page cache integration and demand-paged memory access), zerocopy (Rust crate enabling direct casting of memory-mapped regions to structured data without serialization overhead), and 1 more. A focused set of dependencies that keeps the build manageable.
What system dynamics does netdata have?
netdata exhibits 4 data pools (Journal Files, RRD Circular Buffers), 4 feedback loops, 5 control points, 4 delays. The feedback loops handle polling and retry. These runtime behaviors shape how the system responds to load, failures, and configuration changes.
What design patterns does netdata use?
5 design patterns detected: Memory-Mapped File Windows, Plugin Architecture, Circular Buffer Time Series, Zero-Copy Serialization, Interior Mutability with Guards.
Analyzed on April 20, 2026 by CodeSea. Written by Karolina Sarna.