0.0
A long-lived project that still receives updates
Trifle::Stats is a way too simple timeline analytics that helps you track custom metrics. Automatically increments counters for each enabled range. It supports timezones and different week beginning.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

~> 2.1
>= 0
>= 0
~> 13.0
~> 3.2
= 1.0.0
>= 2.14.0
>= 1.2
>= 4.2
>= 1.4.4

Runtime

~> 2.0
 Project Readme

Trifle::Stats

Gem Version Ruby

Time-series metrics for Ruby. Track anything (signups, revenue, job durations) using the database you already have. No InfluxDB. No TimescaleDB. Just one call and your existing Postgres, Redis, MongoDB, MySQL, or SQLite.

Part of the Trifle ecosystem. Also available in Elixir and Go.

Why Trifle::Stats?

  • No new infrastructure. Uses your existing database. No dedicated time-series DB to deploy, maintain, or pay for.
  • One call, many dimensions. Track nested breakdowns (revenue by country by channel) in a single track call. Automatic rollup across dynamic time granularities (1m, 6h, 1d, etc.).
  • Library-first. Start with the gem. Add Trifle App dashboards, Trifle CLI terminal access, or AI agent integration via MCP when you need them.

Quick Start

1. Install

gem 'trifle-stats'

2. Configure

Trifle::Stats.configure do |config|
  config.driver = Trifle::Stats::Driver::Postgres.new(ActiveRecord::Base.connection)
  config.granularities = ['1h', '1d', '1w', '1mo']
end

3. Track

Trifle::Stats.track(
  key: 'orders',
  at: Time.now,
  values: {
    count: 1,
    revenue: 49_90,
    revenue_by_country: { us: 49_90 },
    revenue_by_channel: { organic: 49_90 }
  }
)

4. Query

Trifle::Stats.values(
  key: 'orders',
  from: 1.week.ago,
  to: Time.now,
  granularity: :day
)
#=> { at: [Mon, Tue, Wed, ...], values: [{ "count" => 12, "revenue" => 598_80, ... }, ...] }

Drivers

Driver Backend Best for
Postgres JSONB upsert Most production apps
Redis Hash increment High-throughput counters
MongoDB Document upsert Document-oriented stacks
MySQL JSON column MySQL shops
SQLite JSON1 extension Single-server apps, dev/test
Process In-memory Testing
Dummy No-op Disabled analytics

Features

  • Dynamic time granularities. Use any interval like 1m, 10m, 1h, 6h, 1d, 1w, 1mo, 1q, 1y.
  • Nested value hierarchies. Track dimensional breakdowns in a single call.
  • Series operations. Aggregators (sum, avg, min, max), transponders, formatters.
  • Buffered writes. Queue metrics in-memory before flushing to reduce write load.
  • Driver flexibility. Switch backends without changing application code.

Buffered Persistence

Every track/assert/assort call is buffered by default. The buffer flushes on an interval, when the queue reaches a configurable size, and on shutdown (SIGTERM/at_exit).

Trifle::Stats.configure do |config|
  config.driver = Trifle::Stats::Driver::Redis.new(Redis.new)
  config.buffer_duration = 5   # flush every ~5 seconds
  config.buffer_size = 100     # ...or sooner when 100 actions are enqueued
  config.buffer_aggregate = true
end

Set buffer_enabled = false for synchronous write-through.

Documentation

Full guides, API reference, and examples at docs.trifle.io/trifle-stats-rb

Trifle Ecosystem

Trifle::Stats is the tracking layer. The ecosystem grows with you:

Component What it does
Trifle App Dashboards, alerts, scheduled reports, AI-powered chat. Cloud or self-hosted.
Trifle CLI Query and push metrics from the terminal. MCP server mode for AI agents.
Trifle::Stats (Elixir) Elixir implementation with the same API and storage format.
Trifle Stats (Go) Go implementation with the same API and storage format.
Trifle::Traces Structured execution tracing for background jobs.
Trifle::Logs File-based log storage with ripgrep-powered search.
Trifle::Docs Map a folder of Markdown files to documentation URLs.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/trifle-io/trifle-stats.

License

The gem is available as open source under the terms of the MIT License.