Fundamentals of Nominal: Visualizing Telemetry at Any Scale
Anthony Mainero
The first in a series of blog posts by the Nominal software team detailing how our platform serves a wide variety of hardware domains with a simple but powerful set of primitives.

Engineers use the Nominal Core platform to test aircraft, satellites, energy systems, industrial systems, and manufacturing processes.
Every hardware program eventually outgrows CSVs, downsampled dashboards, or patched-together tools. Time-scale agnostic, multi-rate visualization is a foundational requirement for serious test engineering, but it’s one of the hardest parts of the stack to get right. Nominal is built on a set of primitives that let engineers ingest and manage messy real-world telemetry on a unified timeline for test & analytical workflows.
We saw this problem over and over again working with hardware teams of all stages, sizes, and domains: engineers spend too much time building, managing, and fighting with their telemetry stack before they could look at the results of their last test.
We engineered Nominal to work flexibly for all sorts of test engineering workflows that a team might need throughout the life of their program: for both live monitoring and post-test analysis, for developmental and operational test, for single asset and multi-asset operations, for real tests and simulation, for tests that run for fractions of a second, as well as those that continue for months on end.
This article focuses on that last capability: making Nominal’s UI work for any time scale.
Origins: what we built first
The earliest iteration of Nominal lived as a minimal cloud-based time series viewer that could ingest a CSV full of telemetry data, plot it as a time series, zoom in to any slice of time, and re-render the time series at the appropriate resolution given the granularity of the data.
Users could then share a link to that view to their colleagues. Opening a link showed the recipient the same range of time that the sender was looking at when they sent the link, at the same resolution.
This version didn’t support live streaming, multi-modality, expressive computation, validation, nor outside data integrations. All those pieces would come later. With that core functionality, our fledgling platform became a launchpad to support a powerful set of end-to-end telemetry operations.
Challenges rendering high-rate data
Telemetry systems commonly run into the same wall: attempting to render every point of data in the range of time queried. These systems quickly fall apart when trying to perform analysis on high-data rate signals over long time periods.
Let’s consider visualizing the pressure through a valve over 24 hours of continuous operation. If the pressure sensor providing that signal returns data at 1kHz—or 1,000 signals per second—that sensor produces 86.4 million data points over that 24 hour time frame.
If the underlying time series uses 8 byte timestamps and 8 byte values, the uncompressed data over that 24 hours amounts to 1.4GB. And that’s just one signal. A test engineer might want to quickly scan over dozens or hundreds of such channels.
We don’t need to render so many data points on the screen. A high-end 4K monitor has a horizontal resolution of about 4,000 pixels. Each pixel on such a monitor needs to cover 22,000 data points per sensor for the 24-hour view, with each pixel representing 22 seconds of time. If the data has sufficient noise or variation within that window of time, the clustering of points over a single moment of time can make it difficult to discern any sense of the distribution of values.
For anyone trying to do telemetry analysis at scale, this performance and behavior make analysis extremely time consuming. Slow UIs can turn a minute’s worth of work into hours, and can become a major bottleneck for a test program that gets delayed waiting for the reports to come back from the latest test event.
Downsampling in Nominal
We call our time series analysis environments “workbooks”, designing them for rapid exploration—zooming, panning, resampling, plotting new channels, computing across channels— so that engineers can iterate on analyses and build reports at the speed of thought. To serve that need, we needed to ensure that the right data could get from our servers to our UI as quickly as possible.
Splitting the time window into buckets
Sending a gigabyte of data to a user’s web browser to show a day’s worth of data was completely untenable. Instead of trying to render every data point, we only needed to render what the end user could actually see: buckets of data, not every point. For a chart that measures 1000 pixels across, we don’t need to return more than 1,000 buckets of data.
When simply querying a single unmodified channel, this seems straightforward: split up the queryable time window into 1,000 smaller buckets of time, scan across each bucket, and return the average for every bucket. Whether we’re looking at 24 hours or 24 microseconds, we can send the same amount of data to our UI and render a time series that covers the time range, no matter the scale.
That intuition has the right shape, but a number of complexities and edge cases make the implementation challenging.
Bucketing complications
As a first consideration, we need to decide what point we want to draw for each bucket. We might say it should be the average value across each bucket’s slice of time, but that doesn’t always provide a representative picture.
If we’re rendering a sinusoidal signal with a period less than our time window, we won’t see clearly that the signal has range and variance. What about a signal value that is mostly stable throughout the data range, but spikes dramatically for just a moment? Obviously the test engineer would want to see that. Each bucket needs to provide not just a single value, but a statistical description of the data within the bucket.
When rendering each pixel on our time series charts, we render shaded areas covering the min, mean, and max of the signal value over the bucket’s slice of time. This gives the user a statistically faithful representation of the underlying signal, not an aliasing artifact or a misleading average. Spikes and drops always surface to the user, no matter the time scale of the analysis.
Naive mean and variance
We also handle overflow when computing the average value within a bucket. A simple mean calculation appears straightforward—sum all values and divide by the count—but at high data rates this becomes dangerous. A bucket representing even a few seconds of a 1 kHz or 10 kHz channel can contain millions of points. Summing those values directly can overflow 64-bit floating point accumulators, and even when it doesn’t, floating-point precision degrades as the partial sum grows larger relative to each new value.
The naïve two-pass method for computing variance makes this worse: first summing large numbers to compute the mean, then subtracting that mean from each value in a second loop. This approach suffers from catastrophic cancellation, prone to producing incorrect results for large datasets. In a telemetry system expected to operate reliably over billions of points, that approach simply isn’t viable.
Even on commodity hardware this can produce silently corrupted summaries that are unacceptable in a test engineering environment where correctness matters as much as performance.
Welford’s algorithm for numerically stable mean and variance
To avoid these complications, we use Welford’s algorithm, a numerically stable, single-pass method for computing mean and variance. It is explicitly designed for massive datasets and streaming contexts, where you may process millions of points per bucket and cannot afford either a second pass or an unbounded accumulator.
Instead of summing all values directly, Welford’s algorithm updates the mean and the second central moment incrementally with each new point, keeping internal values small and tightly bounded. It also maintains numerical stability by updating variance based on the previous mean rather than subtracting large, nearly equal numbers.
This formulation guarantees stable results even for billions of points. Inside Nominal, each bucket maintains a compact set of statistics: min, max, mean, count, and variance. Welford’s algorithm enables each bucket to remain lightweight, accurate, and mergeable across both time and distributed compute boundaries.
By combining visual bucketing with numerically stable streaming statistics, Nominal can downsample billions of raw points into a faithful, high-resolution representation, ensuring that spikes, excursions, noise envelopes, and subtle behaviors remain visible at any time scale, without ever sacrificing correctness, performance, or intuitive behavior.
Variable-rate and derived signals
Our bucketing algorithm must handle signals with varying data rates: real physical phenomena can affect the write speed of sensors, so a 1kHz sensor—intended to write 1,000 points per second—might complete fewer measurements under extreme heat or stress. We cannot assume an even sampling rate.
When performing derived calculations, such as computing the sum of two time series across a window, we also need to consider that those time series might have different data rates, and that their timestamps might be staggered. These types of operations can stack, making it untenable to perform computation on these summarized buckets; instead, math in Nominal is performed point-to-point across the read-only sensor values that engineers send to Nominal. Only when calculation is finished do we start bucketing the data for frontend consumption.
Exporting full-rate and custom-rate data
We designed our export capability to support flexible downstream uses: feeding data into custom analysis scripts, sharing results with external collaborators, or archiving test data in standardized formats. When exporting, users can select which channels to download, including both raw sensor data and derived channels computed within the workbook.
By default, Nominal exports data at its full native rate rather than downsampling, preserving every data point that was ingested or computed. However, engineers often need data at a specific rate that differs from what their sensors originally provided. A flight test might collect GPS data at 10Hz, IMU data at 100Hz, and high-speed sensor data at 1kHz, but the analysis pipeline downstream expects all channels resampled to a uniform 50Hz.
Nominal’s export interface lets you define a custom target data rate or period; the system will then resample all selected channels to match. This resampling respects a critical constraint: we don’t extrapolate data backwards in time. When downsampling from a higher rate to a lower rate, we apply the same bucketing approach over each target time window. When upsampling from a lower rate to a higher rate, we forward-fill values, ensuring that each data point reflects only information that was available at that moment in time.
This temporal causality guarantee is essential for post-processing workflows. Test engineers often need to replay data through control algorithms or simulation environments, and any backwards-looking interpolation would introduce non-causal artifacts that could invalidate the analysis. By maintaining strict temporal ordering in our resampling, exported data remains suitable for causal replay and downstream processing.
Closing thoughts
Telemetry at scale is too important and too hard to manage with patched-together systems. For users that want to look at a lot of telemetry at once, most in-house or off-the-shelf systems buckle under the load.
Nominal set out from its earliest iterations to build the best telemetry engine in the world. Downsampling effectively is a deep topic with a surprising amount of nuance, and one of many issues we’ve seen hamper engineers across domains. Building out a thoroughly-engineered, battle-tested telemetry system shouldn’t be a burden for hardware teams, but all too often tools get in the way.
To work at their best, a test engineer needs an interface that offers low latency, high resolution, and low cognitive load. Visualization and derivation should just work, no matter the time scale, no matter the irregularity of the signal. A clean, intuitive, performant interface reduces the cycle time between tests, moving timelines forward and de-risking programs. It starts with great tools.
If you want to push the boundaries of flight, space, energy, autonomy, or advanced manufacturing, we’d love to build with you.
- If you’re interested in trying Nominal with your team, please reach out to us for a demo.
- Or if you’re inspired by our mission and want to join us, check out our career page.