GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GitHub - managedcode/TimeSeries: TimeSeries, provides convenient tools for working with time series data in C#. It includes classes for accumulating and summarizing data in time frames, as well as storing and compressing the data efficiently

BranchesTags
Open more actions menu

Latest commit

 

History

51 Commits
51 Commits

Folders and files

NameName
Last commit message
Last commit date
.codex
.codex
 
 
.config
.config
 
 
.github/workflows
.github/workflows
 
 
ManagedCode.TimeSeries.Benchmark
ManagedCode.TimeSeries.Benchmark
 
 
ManagedCode.TimeSeries.Orleans
ManagedCode.TimeSeries.Orleans
 
 
ManagedCode.TimeSeries.Tests
ManagedCode.TimeSeries.Tests
 
 
ManagedCode.TimeSeries
ManagedCode.TimeSeries
 
 
docs
docs
 
 
scripts
scripts
 
 
.editorconfig
.editorconfig
 
 
.gitignore
.gitignore
 
 
AGENTS.md
AGENTS.md
 
 
Directory.Build.props
Directory.Build.props
 
 
Directory.Packages.props
Directory.Packages.props
 
 
LICENSE
LICENSE
 
 
ManagedCode.TimeSeries.slnx
ManagedCode.TimeSeries.slnx
 
 
README.md
README.md
 
 
logo.png
logo.png
 
 

Repository files navigation

ManagedCode TimeSeries

ManagedCode.TimeSeries

.NET Coverage Status Release CodeQL Downloads License

Lock-free, allocation-conscious, thread-safe time-series primitives for building fast counters, rolling analytics, and metric pipelines in .NET 10 / C# 14.

Package links open the latest stable release on NuGet; badges update automatically.

Package Latest version Downloads Description
ManagedCode.TimeSeries NuGet Downloads Thread-safe time-series accumulators, summers, and extensions.
ManagedCode.TimeSeries.Orleans NuGet Downloads Orleans serializers and surrogates for the core time-series types.

What is this library?

ManagedCode.TimeSeries is a high-performance .NET time series metrics library. It provides optimized, time-bucketed collections to aggregate events into time series:

  • Accumulators store raw events per time bucket (queue per bucket).
  • Summers store aggregated values per time bucket (sum/min/max/replace).
  • Groups manage many series by key (per endpoint, per customer, per shard, etc.).

It's designed for high-throughput analytics: clicks, tokens, CPU usage, money, events, and any numeric telemetry.

Why use it?

  • Lock-free ingestion for high write rates.
  • Thread-safe reads/writes for multi-threaded pipelines.
  • UTC-normalized timestamps for deterministic ordering.
  • Grouped series for multi-tenant metrics.
  • Orleans-friendly converters and System.Text.Json helpers.

Common use cases

  • Web analytics (page views, clicks, conversion funnels).
  • Infrastructure metrics (CPU, memory, latency, tokens).
  • Billing counters (money, usage, events per window).

Concepts (quick mental model)

  • SampleInterval: bucket size (e.g., 1s, 10s, 1m).
  • Samples/Buckets: ordered view of buckets keyed by UTC timestamps (Buckets is an alias of Samples).
  • MaxSamplesCount: maximum bucket count per series; 0 means unbounded (this is not the event count).
  • DataCount: total events processed (not the number of buckets).
  • UTC normalized: you can pass any DateTimeOffset, but values are normalized to UTC internally; offsets are not stored.
  • Thread-safe: concurrent reads/writes are supported across all public types.

Install

dotnet add package ManagedCode.TimeSeries

Quickstart

1) Make a rolling accumulator (store raw events)

using ManagedCode.TimeSeries.Accumulators;

var requests = new IntTimeSeriesAccumulator(
    sampleInterval: TimeSpan.FromSeconds(5),
    maxSamplesCount: 60); // 60 buckets -> 5 minutes at 5s interval

// Use current time (UTC internally)
requests.Record(1);
requests.Record(1);

Console.WriteLine($"Buckets: {requests.Samples.Count}");
Console.WriteLine($"Events: {requests.DataCount}");

2) Make a summer (store aggregates per bucket)

using ManagedCode.TimeSeries.Summers;
using ManagedCode.TimeSeries.Extensions;

var latency = new NumberTimeSeriesSummer<decimal>(TimeSpan.FromMilliseconds(500));

latency.Record(12.4m);
latency.Record(9.6m);

Console.WriteLine($"Sum: {latency.Sum()}");
Console.WriteLine($"Avg: {latency.Average():F2}");
Console.WriteLine($"Min/Max: {latency.Min()} / {latency.Max()}");

3) Track many keys at once (grouped series)

using ManagedCode.TimeSeries.Accumulators;
using ManagedCode.TimeSeries.Extensions;

var perEndpoint = new IntGroupTimeSeriesAccumulator(
    sampleInterval: TimeSpan.FromSeconds(1),
    maxSamplesCount: 300,
    deleteOverdueSamples: true);

perEndpoint.AddNewData("/home", 1);
perEndpoint.AddNewData("/checkout", 1);

foreach (var (endpoint, accumulator) in perEndpoint.Snapshot())
{
    Console.WriteLine($"{endpoint}: {accumulator.DataCount} hits");
}

4) Serialize/deserialize with System.Text.Json

using ManagedCode.TimeSeries.Accumulators;
using ManagedCode.TimeSeries.Serialization;

var series = new IntTimeSeriesAccumulator(TimeSpan.FromSeconds(1), maxSamplesCount: 10);
series.AddNewData(1);
series.AddNewData(2);

var json = TimeSeriesJsonSerializer.SerializeAccumulator<int, IntTimeSeriesAccumulator>(series);
var restored = TimeSeriesJsonSerializer.DeserializeAccumulator<int, IntTimeSeriesAccumulator>(json);

Console.WriteLine(restored.DataCount); // same as original

5) Orleans serialization (v9)

Converters in ManagedCode.TimeSeries.Orleans are marked with [RegisterConverter] and are auto-registered when the assembly is loaded. Reference the package from your silo and client projects so the converters are available. Converters are provided for int/float/double accumulators, summers, and grouped series, plus generic numeric summers.

Time handling (DateTimeOffset vs DateTime)

  • Public APIs accept DateTimeOffset so callers can pass any offset they have.
  • Internally, timestamps are normalized to UTC (offset zero) for speed and determinism.
  • If you need to preserve offsets, store them separately alongside your metric data.
  • If you do not need custom timestamps, use Record(value) or AddNewData(value) and let the library use DateTime.UtcNow.

Accumulators vs Summers

Type Stored per bucket Best for
Accumulator ConcurrentQueue<T> raw event lists, replay, exact values
Summer T (aggregated) fast stats, memory-efficient counters

Performance tips

  • Keep MaxSamplesCount reasonable to limit memory.
  • Use Record(value) (or AddNewData(value)) unless you must pass custom timestamps.
  • Use summers for high-volume metrics (they avoid storing every event).
  • Avoid locks in code that touches these structures.

Design notes

  • Accumulators use ConcurrentQueue<T> to remain lock-free and thread-safe under concurrent writes.
  • Even in single-threaded runtimes, timers and background cleanup can introduce concurrency.
  • If you need single-thread-only storage, consider using summers or ask for a dedicated single-thread accumulator.

Architecture

  • See docs/Architecture/Overview.md for detailed workflows, data model, and module boundaries.

Development Workflow

dotnet restore ManagedCode.TimeSeries.slnx
dotnet build ManagedCode.TimeSeries.slnx --configuration Release
dotnet format ManagedCode.TimeSeries.slnx
dotnet build ManagedCode.TimeSeries.slnx --configuration Release
dotnet test ManagedCode.TimeSeries.Tests/ManagedCode.TimeSeries.Tests.csproj --configuration Release

Extensibility

Scenario Hook
Custom numeric type Implement INumber<T> and use NumberTimeSeriesSummer<T>
Different aggregation Use Strategy or implement a custom summer
Serialization System.Text.Json helpers in ManagedCode.TimeSeries.Serialization

Contributing

  1. Restore/build/test using the commands above.
  2. Keep new APIs covered with tests (see existing samples in ManagedCode.TimeSeries.Tests).
  3. Keep hot paths lock-free; only introduce locking when unavoidable and document the trade-off.
  4. Update this README if you change behavior or public APIs.

License

MIT (c) ManagedCode SAS.

About

TimeSeries, provides convenient tools for working with time series data in C#. It includes classes for accumulating and summarizing data in time frames, as well as storing and compressing the data efficiently

Topics

accumulatorsummertime-seriestimeseries

Resources

Readme
MIT license
Activity
Custom properties

Stars

23 stars

Watchers

1 watching

Forks

0 forks
Report repository

Releases

Used by

Contributors

Languages

You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.