multiscale-timeseries
TypeScript icon, indicating that this package has built-in type declarations

2.0.0 • Public • Published

multiscale-timeseries

Small utility for maintaining multi-scale timeseries records.

Why? The problem at hand is to record analytics for various events such as page views, user logins, and usage of features for a Web-based software product. This library was created out of the need for a lightweight solution that has the following properties:

  • Represent multiple levels of detail including hours, days, weeks, months, quarters, and years.
  • Age out data to maintain an upper bound on storage for each timeseries record.
  • Persist the timeseries as JSON.
  • Access the analytics data for presentation within the product.

Example Usage

const { increment } = require('multiscale-timeseries');

const date = new Date('2020-10-05T14:32:40.441Z');
const maxEntries = 1,000; // Max entries governing age-out for each interval.
const record = {}; // Can be an empty object or existing record.

// This is the main call - increment a timeseries record based on a date.
const record = increment(record, date, maxEntries);

// The result looks like this:
assert.deepEqual(record, {
  minutes: { '2020-10-05T10:32': 1 },
  hours: { '2020-10-05T10': 1 },
  days: { '2020-10-05': 1 },
  weeks: { '2020-W41': 1 },
  months: { '2020-10': 1 },
  quarters: { '2020-Q4': 1 },
  years: { 2020: 1 },
  all: { all: 1 },
});

Once a record exists, you can increment it again and again. After accumulating maxEntries entries for any given interval, the oldest of the entries are deleted. For example hours entries would be the first to age out.

After incrementing many times, you end up with a record that looks like this:

const date = new Date('2020-12-06T14:32:40.441Z');
const maxEntries = 2; // Low value to demonstrate age-out.

record = increment(record, date, maxEntries);

assert.deepEqual(record, {
  days: { '2020-12-05': 2, '2020-12-06': 1 },
  hours: { '2020-12-05T09': 2, '2020-12-06T09': 1 },
  minutes: { '2020-12-05T09:32': 2, '2020-12-06T09:32': 1 },
  months: { '2020-10': 2, '2020-12': 3 },
  quarters: { '2020-Q4': 5 },
  weeks: { '2020-W41': 2, '2020-W49': 3 },
  years: { 2020: 5 },
  all: { all: 5 },
});

What should maxEntries be?

The point of this library is to have an upper bound on the size of a multiscale timeseries record, regardless of how many times it is incremented. It begs the question, how does maxEntries relate to the size in Kilobytes of the record stored on disk?

A script (sizeEstimator.js in this repo) was developed that simulates updating a timeseries record every hour for one year, using various values for maxEntries, and estimating the size of the output as stringified JSON. Here is the output of that script:

maxEntries Kilobytes
10 2 KB
20 2 KB
30 3 KB
40 4 KB
50 4 KB
60 5 KB
70 5 KB
80 6 KB
90 6 KB
100 7 KB
150 10 KB
200 12 KB
250 15 KB
300 18 KB
350 20 KB
400 23 KB
450 25 KB
500 26 KB
600 30 KB
700 34 KB
800 38 KB
900 42 KB
1000 45 KB
1500 65 KB
2000 84 KB

FAQ

  • Why not just use Google Analytics? With multiscale-timeseries and any lightweight data store, you can roll your own analytics and have full access to the data, so you can present it in your product directly. Other than that, Google Analytics is a perfectly good solution.

Readme

Keywords

Package Sidebar

Install

npm i multiscale-timeseries

Weekly Downloads

3

Version

2.0.0

License

MIT

Unpacked Size

10.2 kB

Total Files

7

Last publish

Collaborators

  • curran