Configuration Reference

Copy Markdown View Source

Store options

All options are passed to the TimelessMetrics child spec:

{TimelessMetrics,
  name: :metrics,
  data_dir: "/var/lib/metrics",
  schema: MyApp.MetricsSchema,
  raw_retention_seconds: 14 * 86_400,
  daily_retention_seconds: 365 * 86_400,
  ingest_workers: 8,
  alert_interval: :timer.seconds(30),
  self_monitor: true,
  self_monitor_labels: %{"service" => "api"},
  scraping: true}

Core options

OptionTypeDefaultDescription
nameatom(required)Store name used to reference this instance in all API calls
data_dirString.t()"data"Directory for the store's SQLite admin data and Rust engine data files
mode:disk | :memory:disk:disk persists data under data_dir; :memory keeps the store ephemeral
schemamodule or %TimelessMetrics.Schema{}TimelessMetrics.Schema.default()Rollup tier configuration
raw_retention_secondspos_integer()604_800How long raw point data is retained (7 days by default)
daily_retention_secondspos_integer()31_536_000How long daily rollup data is retained (365 days by default)
ingest_workerspos_integer()max(div(schedulers, 4), 2)Background workers that drain HTTP ingest queues
alert_intervalpos_integer()60_000Milliseconds between alert evaluation cycles
self_monitorboolean()trueEnable internal self-monitoring metrics
self_monitor_labelsmap()%{}Labels applied to self-monitoring metrics
scrapingboolean()trueEnable the Prometheus scraping subsystem
engine:rust | :legacy:rustEngine selection. :rust is the default and maintained path; :legacy exists only for compatibility and migration work

Legacy-only options

These options apply only when engine: :legacy is used:

OptionTypeDefaultDescription
buffer_shardspos_integer()max(div(schedulers, 2), 2)Number of ETS buffer shards
flush_intervalpos_integer()5_000Automatic buffer flush interval in milliseconds
flush_thresholdpos_integer()10_000Points per shard before immediate flush
segment_durationpos_integer()14_400Segment window size in seconds
compression:zstd:zstdSegment compression container
compression_levelpos_integer()2Zstd level for legacy segment files

For new deployments, do not tune these unless you are intentionally running the legacy engine.

HTTP server options

{TimelessMetrics.HTTP,
  store: :metrics,
  port: 8428,
  bearer_token: "my-secret-token"}
OptionTypeDefaultDescription
storeatom(required)Name of the TimelessMetrics store to serve
portpos_integer()8428HTTP listen port
bearer_tokenString.t() | nilnilBearer token for API authentication. When nil, endpoints are open

Full configuration example

# config/config.exs
config :my_app, :metrics,
  name: :metrics,
  data_dir: "/var/lib/my_app/metrics",
  raw_retention_seconds: 14 * 86_400,
  daily_retention_seconds: 2 * 365 * 86_400,
  ingest_workers: 8,
  alert_interval: :timer.seconds(30),
  self_monitor: true,
  self_monitor_labels: %{"service" => "api"},
  scraping: true
# lib/my_app/application.ex
defmodule MyApp.Application do
  use Application

  @impl true
  def start(_type, _args) do
    metrics_opts = Application.get_env(:my_app, :metrics)

    children = [
      {TimelessMetrics, metrics_opts},
      {TimelessMetrics.HTTP,
        store: metrics_opts[:name],
        port: 8428,
        bearer_token: System.get_env("METRICS_TOKEN")}
    ]

    Supervisor.start_link(children, strategy: :one_for_one, name: MyApp.Supervisor)
  end
end

Container environment variables

When running as a container, these environment variables configure the instance:

VariableDefaultDescription
TIMELESS_DATA_DIR/dataStorage directory
TIMELESS_PORT8428HTTP listen port
TIMELESS_BEARER_TOKEN(none)Bearer token for API auth (unset = no auth)

Tuning guidance

mode

  • Use :disk for normal deployments. This is the durable path.
  • Use :memory for tests, short-lived benchmarks, and ephemeral experimentation.

ingest_workers

These workers drain the HTTP import queue. They matter only for the HTTP ingest path, not direct Elixir writes.

  • Default: good for most deployments
  • Increase: when HTTP import is saturated and CPU is available
  • Decrease: for small embedded deployments where background concurrency is unnecessary

raw_retention_seconds and daily_retention_seconds

  • Raw retention controls how long full-resolution point data stays queryable.
  • Daily retention controls long-term rollup retention.
  • Longer retention improves historical visibility but increases disk usage.

schema

Use a custom schema when your retention tiers need to match your dashboarding horizon.

  • Keep raw data shorter for high-volume operational metrics.
  • Extend daily or monthly tiers for long-term planning and reporting.
  • Treat schema changes as storage-layout decisions, not cosmetic config.

Multiple store instances

You can run multiple independent stores in the same application:

children = [
  {TimelessMetrics, name: :app_metrics, data_dir: "/data/app"},
  {TimelessMetrics, name: :infra_metrics, data_dir: "/data/infra"},
  {TimelessMetrics.HTTP, store: :app_metrics, port: 8428},
  {TimelessMetrics.HTTP, store: :infra_metrics, port: 8429}
]