Changelog

New features, improvements, and fixes.

ClickHouse, now optional

You want funnels, retention, and user profiles for your product. What you don't want is to operate a column database to get them. Until now, Tell's answer was "run ClickHouse" — great at billions of events, overkill on a single VPS.

Now the whole analytics suite also runs on files. ClickHouse didn't go anywhere — you have a second first-class store, and the choice is yours.

One binary, your files

Point Tell at a directory and start sending events. Data lands as Apache Arrow files — an open columnar format any data tool can read — and every query runs directly against them. No database server, no connection strings, nothing else to install.

  • Every report works — funnels, retention, lifecycle, user paths, people profiles, audiences, revenue, group analytics. Same features, same numbers
  • Verified, not promised — a differential test suite runs each metric against both the file store and ClickHouse and requires identical results
  • Your data stays yours — plain files on your disk, in a format DuckDB, pandas, or a Python script can open tomorrow

Or point it at a bucket

Set mode = "s3" and the file store becomes a shared one — AWS S3, MinIO, or Cloudflare R2.

  • Stateless collectors — ingest nodes upload straight to the bucket and keep nothing local. Kill one, start another, no data to migrate
  • Readers scan the same bucket — the dashboard queries what collectors wrote, seconds later
  • Hot local, durable remote — local+upload keeps recent data on disk for fast queries while every file is also uploaded for safekeeping
  • You can see it working — tell status shows upload backlog, and the server checks the bucket is reachable before it starts taking traffic

It cleans up after itself

File stores usually mean a cron job and a shell script. Not here.

  • Background compaction — small files merge into bigger ones automatically, so queries stay fast as data grows
  • Retention windows — tell it to keep 90 days and older partitions are deleted for you
  • On your schedule — tell maintenance runs a one-shot compaction and cleanup pass without restarting the server

ClickHouse or files — your call

Two stores, equal citizens. Every feature works on both, and the differential suite holds them to identical answers — so the choice is about your deployment, not your feature list.

  • Choose ClickHouse for proven scale — billions of events, a mature operational ecosystem, and blazing queries over deep history
  • Choose files for zero moving parts — one binary, an open on-disk format, and object-storage durability without running a database
  • Switch whenever — it's a config line, and your boards, funnels, and audiences don't change

Either way, the same binary scales from a laptop to a fleet of stateless collectors sharing one bucket. And don't assume files are the slow option — early numbers hold up better than we expected. We're benchmarking, not calling a winner.

Know your users

The funnel says 40% drop at checkout. Which 40%? Until you can click a number and see the people behind it, analytics is guesswork with charts.

People — every user, findable

Your product has been identifying users all along — now there's a place to meet them. Browse everyone, search by name, email, or your own user id, and sort by traits or activity.

  • Open anyone's profile — one page per person: who they are, their traits, a full event timeline, session history, and every audience they belong to
  • Scope the directory to an audience — see exactly who's inside "trial users who hit the paywall twice"
  • Erase on request — one admin-only action removes a person's events, sessions, identity, and traits. GDPR requests stop being a database excavation

One person, not three devices

Identity now works the way your product does.

  • Identify with your own user id — email is no longer required
  • Alias merging — connect an anonymous visitor or a legacy id to the canonical user; their history, devices, and traits carry forward
  • Set-once and remove — write a trait only if it's never been set, or delete one, alongside plain updates

Funnels that answer why

Conversion rates tell you that people left. These tell you who, where, and how.

  • Click into any step — see the actual users who reached or dropped there, with names and emails for identified people
  • Break down by any property — split conversion by plan, country, or campaign, with an (other) bucket so the groups always sum to the total
  • Exclusion steps — drop anyone who did a disqualifying event between two steps, like contacting support
  • Ordering modes — require strict sequences when the order matters, or stay loose when it doesn't
  • Time to convert — median, p90, and average time from first step to last, on every funnel

Where they go next

User paths draw a flow diagram of what people actually do after any starting event — or everything that led up to one. Set the depth, cap the branches, scope it to an audience, and watch the real journeys, not the ones on the whiteboard.

Audiences with real logic

  • Nest conditions — AND/OR groups, negation, and "did this at least N times" frequency rules
  • Static cohorts — freeze a list of people and reuse it
  • Snapshots — capture membership on a schedule and chart audience size over time
  • Syncs — push membership to a signed webhook, full or just who entered and left, on a schedule or on demand
  • Applied everywhere — the audience picker now works on funnels, retention, paths, people, and grouped metrics alike

Also in this update

  • Session quality metrics — average, median, and p90 session length, events per session, and bounce rate, splittable by any property
  • Count unique users who did an event, or unique sessions containing it
  • Weekly and monthly active users now use true rolling windows at any granularity
  • An event dictionary with descriptions, tags, and verified flags — and event/property autocomplete everywhere you type one
  • Virtual events — one name for any combination of real events, usable in metrics, funnels, and audience rules alike
  • Events now carry country, city, and network resolved from the source address — geographic breakdowns with zero client work
  • Everything above runs identically on ClickHouse or the file store

Metric trees

Revenue dipped on Tuesday. Six metrics feed it. Which one moved?

Metric trees — see what drives what

Lay your metrics out as a tree: revenue at the top, the inputs that feed it underneath, connected by edges. Then let the data grade your assumptions.

Strategy teams have drawn these on whiteboards for decades. Mixpanel sells them as an Enterprise add-on. Here they're just a feature — on every deployment, including self-hosted.

  • Edges carry evidence — each connection shows the measured correlation between the two metrics over a shared time range, so "signups drive revenue" stops being a slide and becomes a number
  • Formula nodes — derive a node from others with arithmetic, right in the tree
  • Targets — set a goal on any node and see it against actuals
  • One time range for the whole tree — pick an "as of" range and every node answers for the same period
  • Share it — a link shows the live tree to anyone, no login required

Boards you can rearrange

Boards stopped being static grids.

  • Drag cards where you want them — drop zones show you exactly where a card will land
  • Add cards from a picker — choose the metric, the visualization, and the breakdown in one sheet
  • Write between the charts — freeform note cards for context, warnings, and conclusions
  • One time range for the whole board — change it once, every card follows
  • Group boards in the sidebar — named, collapsible folders; drag boards between them, filter to a group
  • Live numbers for link viewers — people you share a board with see current values, not a stale screenshot

Also in this update

  • Command palette — hit Cmd+K, jump to any page, or go straight into your data with a filter already applied
  • A "What's new" dialog inside the app, so your team sees what changed without reading release notes

Put the post on the chart

Tuesday, 6pm: sessions triple. Thursday, someone finally figures out it was a TikTok. By the next spike, nobody remembers which one.

Marks have annotated Tell timelines since day one — releases, incidents, news. Now they carry the actual thing that happened.

Paste a link, keep the story

Drop a URL into a mark and Tell fetches what it is.

  • A TikTok, a YouTube video or Short, a post on X — resolves to its title, author, and thumbnail, and the mark auto-categorizes as a post
  • A GitHub repo or release — pulls the release name and details, no token needed
  • Any other page — falls back to the page's own preview data, and a page with none becomes a clean bare link. Pasting never fails
  • Your own image — override the thumbnail with any image URL when the auto-fetched one isn't the story

See it on the charts

Marks draw directly on your line charts as color-coded vertical lines — release, incident, news, and post each in their own color, labeled, in light and dark theme.

  • The thumbnail comes along — link marks render with their preview, so the viral video sits on the spike it caused
  • Filter per chart — showing only incidents on the error chart and only posts on the signup chart takes one click
  • Edit in place — fix a title, nudge a timestamp, recategorize, or swap the link without recreating the mark

Fetched safely

The fetch runs on your server, so it's built like it.

  • It can't be pointed inward — every fetch is validated against private and reserved addresses, doesn't follow redirects, and carries size and time caps. A blocked fetch quietly degrades to a bare link
  • Rate-limited per user — a runaway script can't turn the preview endpoint into a crawler
  • Audited — every preview fetch lands in the audit log, including blocked ones

Everything from the original marks release still works — create from the CLI, your CI/CD, or plugins, filter by category, keep private drafts.

Security improvements

Nothing in this post is a feature you'll click on. It's the work that keeps a box you run yourself worth trusting — spelled out, because "various security fixes" is not something you can take to a compliance review.

Plugins are fenced in

Plugins run other people's code on your server. This release treats that with the respect it deserves.

  • Sandbox upgraded — the isolation layer that contains WASM plugins now includes fixes for 12 published advisories, among them two critical escape routes on ARM64 hosts. If you run plugins, update
  • Hard resource caps — each plugin instance is limited to 256 MB of memory and force-stopped when it exceeds its time budget. An infinite loop in a plugin can no longer pin one of your cores
  • No redirects — a plugin's HTTP requests stop at the first redirect, closing the trick where an allowed host forwards the request to an internal address, like a cloud metadata service
  • No impersonation — signals emitted by plugins are namespaced, so a plugin can't fake the built-in signals that drive things like firewall automation
  • Verified installs — downloaded plugins are checked against the registry's published checksum before they touch disk. A mismatch refuses to install

Sign-in leaks less

  • Timing tells nothing — a failed login now takes the same time whether the email exists or not, so an attacker can't probe which addresses have accounts
  • Strict signature checks — platform tokens are verified strictly; malformed or non-canonical signatures are rejected outright
  • Keys fail loudly — you can now pin the session signing key in config so logins survive redeploys, and an invalid key stops the server at startup instead of silently generating a new one

The unglamorous list

  • Secret files are created owner-only before any bytes are written — there is no window where a fresh credential is readable by other users on the machine, and a failed permission change is an error, not a shrug
  • The server warns at startup when your config file is world-readable and holds secrets
  • User ids are validated the moment they arrive — empty, oversized, or control-character ids are rejected at the door instead of being silently dropped deep inside
  • Raw SQL queries are checked for blocked functions, scoped to your workspace, and written to the audit log — every one
  • Live streams enforce per-workspace subscriber and payload caps, and malformed subscribe requests that could exhaust memory are rejected
  • Every fetch your server makes on a user's behalf — notification webhooks, Slack delivery, link previews — is validated against private and reserved addresses and rate-limited per user

An audit log that keeps up

Every surface added in this release writes to the audit log from day one: notification channels and alerts, digests, metric trees, the event dictionary, audiences and their snapshots and syncs, board groups, marks and link previews, person erasure, quota transitions, and retention changes — including denied attempts. If it changes state or reads something sensitive, it leaves a record with who, what, and the role they held at the time.

Infrastructure metrics

Tell now ingests infrastructure metrics as a first-class data type. CPU usage, memory trends, network throughput, request latency distributions — stored in ClickHouse and queryable with the same tools you use for product analytics.

Collect with Witness, query in Tell. Your server metrics live next to your product events in the same database.

Three metric types

  • Gauge — point-in-time values. CPU percentage, available memory, disk space, queue depth
  • Counter — cumulative or delta counts. Bytes sent, requests served, errors total. Tell handles both Prometheus-style cumulative and StatsD-style delta temporality
  • Histogram — full distributions with bucket boundaries, count, sum, min, max. Request latency at p50, p95, p99 without pre-aggregation

Every metric carries string and integer labels for slicing by host, service, core, device, interface, status code — any dimension you need.

Query and breakdown

Eleven aggregation functions, all with time bucketing and label breakdown:

  • avg, sum, min, max — standard aggregates across any time window
  • last — most recent observed value, useful for gauge snapshots
  • rate — change over period, for counters that report cumulative totals
  • count — number of data points in the window
  • p50, p75, p90, p95, p99 — percentile queries directly on stored values

Break down any metric by any label. CPU percentage by core, disk I/O by device, network bytes by interface, request latency by endpoint — one query, one chart.

Witness integration

The recommended way to collect infrastructure metrics. Install the Witness agent on your servers and metrics flow automatically — CPU, memory, disk, network, load, TCP state, containers, and top processes out of the box.

  • Same connection — metrics and logs ship over a single TCP connection
  • Hourly checkpoints — cumulative totals alongside deltas, recovers exact counts after outages
  • 15-second resolution — configurable down to sub-second intervals

Any Tell SDK can also send custom application metrics using the same gauge, counter, and histogram types.

Also in this update

  • Delta and cumulative temporality — works with both Prometheus-style and StatsD-style instrumentation
  • Integer labels for numeric dimensions like status codes and ports — efficient range queries without string conversion
  • Session correlation for client-side metrics — tie app performance to user sessions
  • 90-day retention with daily partitioning, configurable per workspace

Live analytics canvases

You're preparing a board review. Signups are up, but retention is flat and churn is creeping. You need one surface that tells the whole story — not six separate charts in six separate tabs.

Canvases — build analytics narratives

Canvases are infinite, zoomable surfaces where you arrange live metric cards, text, images, shapes, and embeds into a single visual story.

  • Drop in a metric card — pick an event, choose a visualization (line chart, bar, table, funnel, retention grid), and it updates live with your data
  • Connect elements with edges — draw straight or curved lines between cards to show cause and effect, with arrows, labels, and anchor points
  • Group with sections — wrap related cards in collapsible frames to organize complex narratives
  • Pin your most important canvases — pinned canvases float to the top of your workspace list
  • Share with a link — generate a public URL that anyone can view without logging in, with optional expiration and rate limiting

AI canvas tools — create dashboards by asking

Your AI assistant can now build and manage canvases directly. Ask it to create a canvas, add metric cards, run every card to pull fresh data, or duplicate an existing canvas as a starting point.

  • "Create a canvas with daily signups and retention side by side" — the assistant builds the layout, adds the metric cards, and configures the queries
  • "Run my Q1 review canvas" — executes every metric card at once and returns the results in the conversation
  • "Duplicate last month's board and update the date range" — deep-copies the canvas with fresh IDs, ready to edit

Accurate analytics

Audience filters now work consistently across every metric type. When you select an audience, funnels, retention grids, lifecycle charts, segments, and ML predictions all respect it. Before, some metrics silently ignored your filter.

  • User counts reflect real people — each user is counted once per period, not once per session. If your DAU drops after this update, that's the correct number
  • Stickiness ratios reflect true engagement — DAU/MAU now uses a rolling 30-day window instead of a cumulative total. Ratios will appear higher because they're no longer diluted by every user you've ever seen
  • Funnels respect your filters — global filter conditions (country, plan, platform) now apply to every funnel step, not just the first

Richer session exploration

Explore sessions with six new fields visible out of the box — device model, operating system, OS version, app version, region, and city. Filter and break down by any of them without writing custom queries.

Also in this update

  • Start your server with tell run — the old tell serve command has been renamed
  • Event names with special characters are now properly escaped, closing a potential injection vector

Witness — server monitoring agent

Witness is a standalone binary written in Rust that ships logs and collects system metrics from your servers. No runtime dependencies, no garbage collector, no Docker — one 1.2 MB file that handles both data types over a single TCP connection.

4 MB of memory at idle, 7 MB under load. Witness handles collection — Tell handles the pipeline. Transforms, routing, multiple sinks, PII redaction — that runs centrally in Tell, not on every host. This is why Witness is 1.2 MB and 4 MB of memory while Vector needs 46 MB on disk and 40 MB to do the same job: Vector is the entire pipeline on every machine. With Tell, the agent just collects and ships — Tell processes the rest at 64M events/sec.

curl -sSfL https://tell.rs/agent | bash

Install, point at your Tell server, and data flows within 15 seconds.

Log shipping

Tails your log files and forwards every line to Tell. System logs, nginx access logs, database slow queries, application output — anything that writes to a file on disk.

  • Works immediately — ships system, web server, and database logs by default. New files are discovered automatically without restarting
  • Fast — 76 ns per log line. Batched and shipped over a persistent TCP connection in the background
  • Rotation safe — handles both rename and copytruncate rotation. Tracks files by inode, drains the old file to the last line before switching
  • Crash recovery — file positions saved after every poll cycle. A crash may re-send up to ~250ms of recent lines, but never skips any
  • Backpressure — when the send channel is full, the agent stops reading and the filesystem becomes the buffer. No data loss, no memory growth

System metrics

Collected every 15 seconds (configurable). All enabled by default, individually toggleable.

  • CPU — per-core user, system, idle, iowait, and steal percentages
  • Memory — total, available, used, cached, and swap
  • Disk — read/write throughput per device, filesystem space per mount
  • Network — bytes, packets, errors, and drops per interface
  • Load — 1, 5, and 15 minute averages
  • TCP — connection counts by state
  • Containers — CPU and memory per container via cgroups v2
  • Processes — top N by CPU and memory usage

30 ns per metric, zero steady-state allocations. Counter metrics (disk, network) are shipped as deltas with hourly cumulative checkpoints — if data is lost during an outage, the next checkpoint recovers exact totals.

Reliability

  • Memory safe — no buffer overflows, no use-after-free, no data races. Unsafe is limited to system call wrappers
  • No panics — a failing metric collector or unreadable log file never takes down the process. Errors are handled with early returns, failed ticks retry automatically
  • Independent modules — if disk stats fail (e.g., permission error), CPU, memory, network, and every other collector keeps reporting. No cascading failures
  • Counter safe — kernel counter wraps and resets after reboots are handled gracefully. Always valid values, never negative numbers
  • Disk-buffered delivery — when the server is unreachable, unsent data is written to disk and drained on the next successful connection. Oldest data evicted when the buffer is full
  • Graceful shutdown — on SIGTERM, the agent drains all queues, saves log offsets, and persists unsent data to disk. Nothing lost between stop and start
  • Config reload — send SIGHUP to pick up config changes without dropping a single line or metric

Witness is built on the Tell Rust SDK. To send custom events, logs, or metrics from your own Rust applications — cargo add tell.

Rust SDK — metrics

The Tell Rust SDK supports product analytics, structured logging, and now infrastructure metrics from a single dependency. Fast and lightweight — 80 ns per call, 10M events/sec delivered. Your thread serializes, encodes, and moves on while the background worker batches and ships over a persistent TCP connection.

API

Fire-and-forget, thread-safe, synchronous calls with async background delivery.

  • Events — track, identify, group, revenue, alias. User behavior, conversion, identity resolution
  • Logs — structured logging at any severity level with service tagging and typed payloads
  • Metrics (new) — gauge, counter, histogram with typed labels and optional source tagging
// Events
client.track("user_123", "Page Viewed", props! { "url" => "/pricing" });

// Logs
client.log_error("connection refused", Some("db"), props! { "host" => "db.internal" });

// Metrics
client.gauge("cpu_percent", 72.5, &[("core", "0")]);
client.counter("http_requests", 1.0, &[("method", "GET"), ("status", "200")]);

Metrics (new)

Monitor application performance and system resources from your Rust code. Three metric types, all at 30 ns per call with zero steady-state allocations.

  • Gauge — point-in-time values: CPU percentage, memory usage, queue depth, active connections
  • Counter — incremental counts: HTTP requests, errors, bytes processed. Delta by default, cumulative optional
  • Histogram — full distributions with bucket boundaries, count, sum, min, max. Request latency at p50, p95, p99 without pre-aggregation

All three types support typed labels for breakdown by any dimension — endpoint, status code, host, region.

Disk-buffered delivery

Unsent data survives process restarts and network outages. The Witness server monitoring agent uses this to guarantee delivery across network failures and service restarts. Enable it in your own applications with one config line:

TellConfig::builder("your_api_key")
    .buffer_path("/var/lib/myapp/tell-buffer")

Batches are written to disk when the server is unreachable and drained on the next successful connection. Default buffer size is 64 MiB.

Get started

github.com/tell-rs/tell-rs

Multi-tenancy

Tell now isolates each workspace into its own database. Events, sessions, and logs from one workspace can never appear in another — not in queries, not in dashboards, not anywhere.

Workspace isolation

Each workspace gets a dedicated database. Data boundaries are enforced at the query level — there's no shared table to accidentally leak across.

Ingestion keys — create and rotate instantly

Manage the keys your SDKs and collectors use to send data. Create a key, name it, and start ingesting immediately — no server restart required.

  • Create from the CLI — tell apikeys new mobile-prod generates a key and shows it once. It's live in the pipeline the moment it's created.
  • List and delete — tell apikeys shows all keys by name and prefix. tell apikeys delete revokes a key instantly.
  • API access — admins can manage keys programmatically via REST endpoints for automation and CI/CD workflows.

Also in this update

  • Funnels now align timestamps correctly and calculate drop-off rates accurately
  • Disconnected signal subscribers automatically receive missed events when they reconnect
  • tell login auto-derives the server name from the hostname and validates the connection before prompting for credentials

Signals

Tell now includes a workspace-scoped pub/sub system. Transformers and plugins emit typed signals when something notable happens. Any number of subscribers can listen, filter, and act on them — from the CLI, browser, or scripts.

Built-in signals today:

  • ip.banned / ip.unbanned — an IP crossed your failure threshold
  • pattern.new — a new recurring log structure was discovered
  • threshold.crossed — event volume exceeded your configured window

Plugins can emit any signal kind they choose — the source is tagged with the plugin name automatically.

Subscribe with tell signals. Filter by kind (--kind ip.*) or source (--source transform:jail:*). Add --json to pipe to scripts, webhooks, or alerting. From the browser, subscribe over Server-Sent Events with the same filters.

New: Multi-server auth

Register multiple Tell servers and switch between them without re-entering credentials.

  • tell login https://prod.acme.com — registers, authenticates, makes it active
  • tell login prod — switches instantly, no password prompt if your token is valid
  • tell workspace use 2 — sets the default workspace for the active server

Also in this update

  • The API server now binds to localhost by default — safer out of the box
  • Plugins auto-fix file ownership when installed as root
  • Cumulative totals now shown alongside per-second rates in metrics output

Routing & transforms

Send your data to multiple destinations at once. Logs to analytics, events to cold storage, everything to archive — each routing rule adds destinations based on what's flowing through. No duplication, no workarounds.

Transforms now apply selectively. Define a transform once, reference it from any rule, and chain multiple transforms in sequence. Each transform declares what it cares about — a service name, a log level, an event type — and only processes matching data. Everything else passes through untouched.

  • Targeted processing — a pattern matcher on sshd logs touches only the 2% it matches. The rest flows through unaffected.
  • PII redaction at scale — emails, phone numbers, and SSNs are stripped at millions of events per second. Compliance adds no meaningful latency.

Five built-in transforms:

  • Pattern matcher — cluster similar log lines into patterns
  • Redact — strip PII at ingest time. Emails, phone numbers, SSNs are masked before data hits storage — GDPR and CCPA compliance built into the pipeline
  • Filter — drop or keep messages by field value
  • Reduce — aggregate messages in time windows
  • Jail — ban IPs that exceed failure thresholds

IP banning

Automatic fail2ban-style threat response, built in. Set a failure threshold, a time window, and a ban duration. IPs that cross the line are banned automatically, with optional escalation for repeat offenders.

  • Escalating bans — first ban is 1 hour, second is 2, third is 4, up to your configured maximum
  • CIDR ignore lists — internal networks and monitoring IPs skip banning entirely
  • Signals — ip.banned and ip.unbanned fire in real time. Subscribe with tell signals --kind ip.* or pipe --json to scripts and webhooks

New: CLI management

Manage boards, workspaces, and saved metrics without opening the dashboard.

  • tell boards — list, create, delete, pin, and share dashboards. Generate public links with tell boards share <id>
  • tell workspace — list workspaces, create new ones, manage members, and invite with tell workspace invite <email> --role editor
  • tell metrics saved — save, list, and delete metric definitions for reuse across boards and canvases

Analytics

A complete product analytics toolkit. Analyze conversion funnels, track retention cohorts, define audiences by behavior, break down any metric by dimension, and compute KPIs from formulas. Users are resolved across devices automatically — the same person on mobile and desktop counts once.

Audiences

Define user segments by combining property filters, user traits, and behavioral rules. "Users in the US on the enterprise plan who purchased in the last 30 days and viewed pricing this week" — all in one audience definition.

  • Property filters — match on country, device type, or any event field
  • Behavioral rules — performed or didn't perform an event within a time window
  • Real-time counts — audience size updates as new events arrive, no manual refresh

Funnels & retention

Track how users move through multi-step flows and whether they come back.

  • Funnels — define 2-10 steps in sequence with a conversion window. See per-step drop-off rates, overall conversion, and breakdowns by country, device, or plan
  • Retention — cohort grids at daily, weekly, or monthly granularity. Each cell shows what percentage of a cohort returned in period N

Groups

Track companies, teams, and organizations alongside individual users. Link users to groups, store group traits like plan, industry, and seat count, and analyze metrics at the group level.

  • B2B analytics — count active companies, measure engagement per organization, compare metrics across teams
  • Group traits — attach metadata to any group and use it to filter or break down queries

Also in this update

  • Break down any metric by country, browser, plan — ranked by volume
  • Compute KPIs with formulas over named metrics — conversion rate, ARPU, any arithmetic expression
  • First-time queries for activation analysis — when did each user first do X
  • Per-user aggregation for power user analysis and distribution queries
  • Split any query by where data originates — website, mobile app, docs site
  • AI assistant can query audiences, funnels, retention, and grouped metrics
  • tell login supports magic link authentication

Marks

Marks are timeline annotations — a deploy, an incident, a release — pinned to your analytics so you can see what happened when a metric moved. Create them manually, from CI/CD, or automatically from plugins.

  • Manual — tell mark "Shipped v2.0" --category release from the CLI, or via the API
  • Automated — your CI/CD pipeline creates a mark on every deploy, with a link back to the commit
  • Plugin-emitted — plugins auto-annotate your timeline. When the GitHub plugin detects a release, or Cloudflare sees a traffic anomaly, a mark appears automatically

Categories

Marks carry a category that signals what kind of event it was:

  • Release — version deployments, feature launches, config changes
  • Incident — outages, degradation, error spikes
  • News — press coverage, announcements, external events that affect your metrics

Filter by category to see only what matters — tell mark list --last 30d --category incident shows recent incidents.

Private and public

Marks default to public (visible to workspace members). Mark something private and only you see it — useful for personal hypotheses, draft annotations, or notes you're not ready to share.

AI assistant

Your AI assistant can create and query marks. Ask it to annotate a deploy, list recent incidents, or find what changed around a date range.

New: Interactive explorer

Explore your data with tell -i. Six views in a terminal-based interface:

  • Status — live throughput and connection stats
  • Query — direct SQL access to your analytics
  • Tail — live stream of incoming data
  • Boards — browse and view dashboards
  • Ask — natural language queries powered by AI

Also in this update

  • Sign in with Tell — OAuth for team authentication
  • tell update checks for newer versions
  • Per-workspace throughput visible in tell status

Plugins

Pull metrics from external services directly into your analytics. Stripe payments, Meta ad spend, Klaviyo campaigns, GitHub activity, Cloudflare traffic — 15 integrations bring your business data into Tell on a schedule, alongside your product events.

See Stripe MRR next to daily active users. Compare Meta ad spend with signup conversion. Track GitHub stars alongside feature adoption. Plugin data and event data live in the same database — query and dashboard them together.

Integrations

Each plugin pulls point-in-time snapshots on a configurable schedule — daily MRR, hourly traffic stats, campaign performance at any interval. 15 plugins available, 276 metrics total:

  • Payments — Stripe (charges, subscriptions, MRR, disputes), Shopify (orders, revenue, customers, inventory)
  • Email & SMS — Klaviyo (campaigns, flows, lists, subscribers), Resend (delivery, bounces, domains)
  • Advertising — Meta Ads (spend, reach, impressions, conversions), Bitly (clicks, geography, devices)
  • App stores — Appbot, AppFigures, AppFollow, AppTweak, ASODesk, MobileAction (rankings, reviews, ratings, ASO)
  • Infrastructure — Cloudflare (DNS, traffic, security, cache performance)
  • Development — GitHub (stars, forks, issues, PRs, commits per repo)
  • Links — Dub (clicks, leads, sales, geography)

Install and pull

Discover plugins from the registry, install, configure, and start pulling — all from the CLI.

  • tell plugin search stripe — find plugins by name or category
  • tell plugin install stripe — install from the registry
  • tell plugin info stripe — view available metrics, datasets, and setup guide
  • tell plugin pull my_stripe — test a one-shot pull or let the scheduler run it on cron

Each plugin includes a setup guide that walks you through API key creation for that service.

Build your own

Plugins are WASM components. Write in Rust (or any language that compiles to WebAssembly), implement a pull function that returns metrics, and publish to the registry.

  • Rust SDK — typed metric builders, timestamp helpers, HTTP client
  • Sandboxed — plugins can only make HTTP requests to their declared hosts
  • tell plugin publish — push to the registry for others to install

Tell 2.0

Tell, rewritten in Rust. Ingest product events, structured logs, and business data from multiple sources. Route to multiple storage formats. Sub-millisecond end-to-end.

Sources

Three ingestion paths:

  • TCP — high-throughput binary ingestion for SDKs and collectors, with API key authentication
  • HTTP — JSON ingestion for web and mobile, with API key authentication
  • Syslog — TCP and UDP receivers for infrastructure logs, assigned to a workspace per port

Storage

Six destinations, each optimized for its use case:

  • ClickHouse — real-time analytics queries over events, sessions, and logs
  • Arrow IPC — fast columnar format for hot data and local exploration
  • Parquet — compressed columnar archive with Snappy, Zstd, or LZ4 compression
  • Disk — binary and plaintext formats with log-level separation and optional compression
  • Stdout — structured output for debugging and development
  • Null — discard sink for benchmarking ingestion throughput

Route the same data to multiple destinations at once — analytics to ClickHouse, archive to Parquet, plaintext logs to disk.

Live tail

Stream data through your terminal in real time with tell tail. Filter by source, type, or content to watch exactly what's flowing through your system.

Also in this update

  • DAU, MAU, and retention queries out of the box
  • 18 AI tools for analytics via MCP
  • API key auth and role-based access — Viewer, Editor, Admin, Platform
  • Workspace isolation — each workspace in its own database