ZoneTree.Analytics 1.0.0

Prefix Reserved
dotnet add package ZoneTree.Analytics --version 1.0.0
                    
NuGet\Install-Package ZoneTree.Analytics -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ZoneTree.Analytics" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ZoneTree.Analytics" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="ZoneTree.Analytics" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ZoneTree.Analytics --version 1.0.0
                    
#r "nuget: ZoneTree.Analytics, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ZoneTree.Analytics@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ZoneTree.Analytics&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=ZoneTree.Analytics&version=1.0.0
                    
Install as a Cake Tool

ZoneTree.Analytics: Millions of events. One clear picture. Embedded analytics for .NET.

ZoneTree.Analytics

Understand your traffic. Measure your product. Own your data.

Web analytics, custom events, and telemetry inside your .NET application.

ZoneTree.Analytics on NuGet Targets .NET 8, 9, and 10 MIT license

ZoneTree.Analytics is an embedded analytics engine built on ZoneTree. Record events, keep the dataset on your infrastructure, and query it directly from C#. The engine runs in your process and requires no external database or separate analytics service.

Packages

Package What it adds
ZoneTree.Analytics The engine: background ingestion, persistent storage, retention, web reports, and the typed C# query API. Its only direct package dependency is ZoneTree.
ZoneTree.Analytics.AspNetCore ASP.NET Core integration: dependency injection, server-side page view tracking, a cookie-free browser tracker, and a reporting API.

Both packages target .NET 8, 9, and 10.

What you can build

Use case What you can measure
Website analytics Visitors, page views, sessions, bounce rate, popular pages, sources, campaigns, browsers, and devices
Product analytics Signups, purchases, revenue, behavioral segments, and conversion funnels
Service telemetry Event counts, durations, percentiles, histograms, error rates, and business metrics
Multi-site reporting Site-scoped events and reports for multiple websites, applications, or tenants in one engine
  • One query model. Combine metrics, filters, dimensions, formulas, time buckets, and period comparisons through a typed C# API.
  • Pre-aggregation for recurring reports. Matching rollups and optional indexes answer recurring reports; queries they cannot answer fall back to retained event history. Query plans expose coverage and warnings.
  • Privacy-conscious defaults. Cookie-free collection, daily anonymous identity rotation, and no stored raw IP addresses or user-agent strings.
  • Application-owned storage. Background ingestion, configurable retention, and persistent ZoneTree stores.
  • Room to customize. Plug in event filters, enrichers, bot detectors, a user-agent parser, or a geolocation provider. Bot traffic can be excluded or reported separately.

Quick start

In a .NET console project, install the engine:

dotnet add package ZoneTree.Analytics

Replace Program.cs with this complete example:

using ZoneTree.Analytics;
using ZoneTree.Analytics.Web;

await using var analytics = AnalyticsEngine.Open("data/analytics");

// Track a page view and a business event for the same identified visitor.
var pageView = AnalyticsEvent.PageView("https://example.com/pricing");
pageView.VisitorId = "customer-42";
await analytics.TrackAsync(pageView);

await analytics.TrackAsync(new AnalyticsEvent("purchase")
{
    VisitorId = "customer-42",
    Dimensions = { ["plan"] = "pro" },
    Values = { ["revenue"] = 49.0 },
});

// Make the events visible before reading them in this short-lived example.
await analytics.FlushAsync();

var traffic = await analytics.Web.GetSummaryAsync(new WebReportRequest
{
    Range = DateRange.LastDays(30),
});

var sales = await analytics.QueryAsync(new AnalyticsQuery
{
    Event = "purchase",
    Range = DateRange.LastDays(30),
    Metrics = { Metric.Events, Metric.Sum("revenue") },
});

Console.WriteLine($"Page views: {traffic.Summary.PageViews}");
Console.WriteLine($"Revenue: {sales.Totals[Metric.Sum("revenue")]:F2}");

Run it with dotnet run. On an empty dataset, it records one page view and revenue of 49.00. The data remains in data/analytics between runs.

Keep one engine per data directory open for the application's lifetime. Events are processed in the background, with an aggregate flush interval of two seconds by default. Normal reporting does not need an explicit flush; this example uses one so its immediate read includes the events it just tracked. Await disposal at shutdown to drain the queue and flush remaining work.

Add it to ASP.NET Core

Install the integration package in an ASP.NET Core project:

dotnet add package ZoneTree.Analytics.AspNetCore

This minimal Program.cs registers the engine and tracks successful HTML page responses:

using ZoneTree.Analytics.AspNetCore;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddZoneTreeAnalytics(
    options => options.DataDirectory = "data/analytics");

var app = builder.Build();
app.UseZoneTreeAnalytics();

app.MapGet("/", () => Results.Content(
    "<!doctype html><html><body><h1>Hello analytics</h1></body></html>",
    "text/html"));

await app.RunAsync();

Dependency injection owns the shared engine and disposes it at host shutdown. Inject IAnalyticsTracker to record custom actions, or AnalyticsEngine to query reports.

  • Browser collection: map app.MapZoneTreeAnalytics() and load /_analytics/script.js on your pages. Choose either server middleware or browser tracking for each page view to avoid double counting.
  • Reporting API: map app.MapZoneTreeAnalyticsApi(), and protect it with app.MapZoneTreeAnalyticsApi().RequireAuthorization() in a host with authentication and authorization configured. Multi-site applications should also configure AuthorizeSite for site-level access.

The ASP.NET Core guide covers collection choices, proxy configuration, and reporting access.

Ask more of your events

The general query API supports totals, grouped reports, time series, and formulas. After tracking purchases with a plan dimension and a revenue value:

var revenue = Metric.Sum("revenue");
var averageOrder = revenue / Metric.Events;

var report = await analytics.QueryAsync(new AnalyticsQuery
{
    Event = "purchase",
    Range = DateRange.ThisMonth,
    Interval = TimeInterval.Day,
    GroupBy = { "plan" },
    Metrics = { Metric.Events, revenue, averageOrder },
    Compare = ComparisonPeriod.PreviousPeriod,
});

foreach (var row in report.Rows)
    Console.WriteLine($"{row.Bucket:yyyy-MM-dd} | {row["plan"]}: {row[revenue]:F2} revenue");

Console.WriteLine($"Average order: {report.Totals[averageOrder]:F2}");

Totals evaluate formulas over the range's totals. Here, the overall average order value is total revenue divided by the number of purchases.

Question Tools
Where do visitors come from? Web breakdowns by source, channel, campaign, and referrer
Which plans generate revenue? Custom dimensions, numeric aggregates, and metric formulas
What did purchasers view? Visitor or session segments based on recorded behavior
Where do visitors drop off? Ordered funnels with a configurable conversion window
How slow are background jobs? Percentiles, histograms, moving averages, and time buckets

Explore querying, segments and funnels, and the query reference for supported combinations and metric semantics.

A dashboard you can host

Explore traffic, acquisition, audience, events, funnels, and bot activity, run custom queries, and export reports. The dashboard is a .NET server with a static UI, built on these packages. It ships as source in the GitHub repository, not as a NuGet package.

ZoneTree Analytics dashboard showing visitor trends, page views, sessions, and acquisition reports

The dashboard guide covers running it with sample data, release builds, and deployment.

Performance

A documented benchmark measures annual reports with previous-period comparisons over 5 million generated events spanning 365 days, including configuration, query plans, individual timings, and methodology.

Matching rollups answer recurring reports from aggregates. Segments, funnels, and unsupported aggregate combinations can require event scans. The benchmarking guide explains how to measure your own workload.

Privacy and data ownership

The default identity strategy recognizes anonymous visitors within a UTC day using a rotating hash. Explicit visitor IDs are keyed hashes and remain stable across days. Raw IP addresses and user-agent strings are used in memory for identity and enrichment, then discarded. Page query strings are excluded by default.

Custom dimensions retain the values your application supplies, so choose what to collect. Configure dimension allow and deny lists, geography precision, identity strategy, and retention to fit your use case. Geography enrichment requires a geolocation provider.

Visitor erasure removes an explicit visitor's retained raw events, dimension-index copies, and active session state. Existing aggregate rollups are not recomputed. Read privacy and identity and retention and erasure for the full behavior.

Operating the engine

Concern What to know
Storage ownership One engine exclusively owns a data directory, including across processes. Keep it on persistent storage. Replicas with separate directories have separate datasets.
Ingestion pressure The queue is bounded. Track drops events on a full queue by default; TrackAsync waits asynchronously for space. Both return whether the event was accepted. Monitor dropped-event statistics and configure request tracking's queue behavior as needed.
Freshness and durability Aggregates are buffered until a successful flush. A crash can lose unflushed aggregates; persistent records follow ZoneTree's write-ahead log guarantees. Await clean shutdown.
History Raw events default to 90 days; hourly rollups to 400 days; daily rollups are kept indefinitely. Hour and Day are the default enabled rollup tiers.
Coverage and counts Inspect query plans and warnings when history or aggregates cannot cover a request. At default precision, unique counts are exact up to 4,096 identities per row, then have about 0.8% standard error.

Use analytics.GetStatistics() and host logging to monitor the engine. See deployment and lifecycle for scaling and backups, and time and accuracy for identity, count, and reporting semantics.

Documentation

Start here Go deeper
Getting started Architecture
ASP.NET Core integration Configuration reference
Web reports Rollups and query planning
Product analytics Secondary indexes
Service telemetry HTTP API reference
Sites and tenants Extensibility

Feedback

Bug reports and focused pull requests are welcome on GitHub. For a reproducible report, include the package version, runtime, relevant options, and a small example in a GitHub issue.

License

Released under the MIT license. Built on ZoneTree.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on ZoneTree.Analytics:

Package Downloads
ZoneTree.Analytics.AspNetCore

ASP.NET Core integration for ZoneTree.Analytics: dependency injection, server-side page view tracking middleware, a cookie-less JavaScript tracker with a beacon endpoint, and a reporting API.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 0 10/15/2026