Command line / metrics
metrics
tinystore metrics reads and writes a store's metrics from a shell, with no
SDK. names, read and aggregate read beside the program or server that
holds the directory. ingest writes the Prometheus text that an exporter
serves, or that a script prints, and delete removes a series; both write
through the server that holds the directory, or start one.
tinystore metrics ./data names
tinystore metrics ./data read ping_rtt_ms --where target=poland --since 1h
tinystore metrics ./data aggregate ping_rtt_ms --since 1h --every 10m --op max --by target
curl -s localhost:9100/metrics | tinystore metrics ./data ingest --label instance=web-1
tinystore metrics ./data delete ping_rtt_ms target=polandSee what a store holds
tinystore metrics ./data names
tinystore metrics ./data names http_ # names that start with http_ping_lost_total counter 6 series keep 30d newest 2s ago
ping_rtt_ms gauge 6 series keep 30d newest 2s ago--json gives one object per name, with its unit, help and times in UTC. A
store with many names prints the first 1000; the last line says which name
--after starts the next page at.
Read samples
tinystore metrics ./data read ping_rtt_ms --where target=poland --from 14:32 --to 14:33 --gaps 5sping_rtt_ms{target="poland"} 26 Oct 14:32–14:33 Europe/Moscow · 46 samples
14:32:00 23.1
14:32:01 22.9
14:32:02 23.4
· 15s without samples
14:32:17 24.0- The first line of each series names it and the range that was read, in this
machine's time zone. Without
--since,--fromor--to,readreads the last hour. --fromand--totake14:30for today,2026-10-25T03:00for a date, both in this machine's zone, or a time with its offset, such as2026-10-25T00:00:00Z.--where target=polandkeeps the series whose label matches. Usestatus=500,502for either value,env!=devfor neither, andhost=api-*for a prefix. Give--whereagain for more labels.--gaps 5smarks every place where a series had no sample for longer than five seconds. Without it,readguesses nothing about a series' step.readprints 1000 samples at most, and says on stderr how many more there were. Narrow the range, or raise--limit.
--json prints one object per sample, its time in UTC:
{"labels":{"target":"poland"},"name":"ping_rtt_ms","time":"2026-10-26T11:32:00Z","value":23.1}A value that JSON can't hold, NaN or an infinity, comes as text: "NaN",
"+Inf", "-Inf". When --limit cut the output, the last line says how
many samples it left out: {"more":2591000}.
Aggregate
tinystore metrics ./data aggregate ping_rtt_ms --since 1h --every 10m --op max --by targetping_rtt_ms max every 10m 26 Oct 13:40–14:40 Europe/Moscow
finland poland sweden
13:40:00 31.2 24.0 40.1
13:50:00 30.8 1012.5 39.7--opiscount,sum,avg,min,max,increase,rate,delta,first,last, orpand a rank, such asp95.--every 10mmakes a bucket every ten minutes. Without it, the range is one bucket.--by targetmakes a group, a column, per value of the label.- A terminal gets a table. When the columns don't fit, each bucket gets a line
of its own.
--jsongives one object per bucket.
Write a scrape or a file
curl -s localhost:9100/metrics | tinystore metrics ./data ingest --label instance=web-1
tinystore metrics ./data ingest --keep 30d < scrape.txtwrote 1834 samples to ./dataingestreads stdin to its end and writes every series of the text, or none. A line it cannot read fails the whole text, and the error names the line.- A sample that the text gives no time gets the time the text was read.
- A name's kind comes from the text's
# TYPEline. A name with no# TYPEis a gauge. --label instance=web-1adds a label to every series. Give it again for more labels.--keep 30dsets how long each name of the text keeps its samples, as the SDKs'keepdoes.
A script can print the text itself. Each line is a name, its labels, a value and, if you have one, a time in milliseconds:
printf 'ping_rtt_ms{target="poland"} 23.1 1793014320000\n' | tinystore metrics ./data ingestDelete a series
tinystore metrics ./data delete ping_rtt_ms target=polanddeleted ping_rtt_ms{target="poland"}delete removes the one series whose labels are exactly the ones given, as
the SDKs' delete does. A name alone names its series without labels, so
delete ping_rtt_ms removes nothing from a metric whose series all have a
target.
Who writes
Who holds ./data | What a write does |
|---|---|
tinystore serve or an SDK's sidecar | writes through it |
| nothing | starts a sidecar, which stops 30 seconds after its last client, and says so |
a program that opened it embedded | refuses and exits 1 |
tinystore metrics ingest: started a server for ./data; it stops 30 s after the last clientSeveral commands can write at once: the first one starts the sidecar, and the
others write through it. A program that opened the store embedded keeps it
inside its own process, so no other process can write to it:
tinystore metrics ingest: a program holds ./data inside its own process, so no other process can write to it
open it in that program with a sidecar, or let `tinystore serve ./data` hold itA directory without a store is refused, and nothing is created in it. Run the
program or tinystore serve there once to make the store.
Limits and defaults
| What | Value |
|---|---|
| a name's keep, when none given | 30 days |
| the largest text | 2 MiB, the largest message the server takes |
| a sidecar's idle time | 30 seconds after its last client |
| the wait for a server | 15 seconds to start, 10 for an answer |
See also
- Ingesting: the same writes from a program, and what the engine keeps.
- status and logs: see which server holds a directory.