muscles

Features

Everything muscles does, with the main features first.

What companies choose muscles for

01

Time series, rollups and logs

Tables sort by time, rollups answer time-bucket queries from rows that are already summed up, and views keep aggregates up to date as rows arrive.

Available

Rollup ladders

CREATE ROLLUP builds a ladder of resolutions, such as one second, one minute and one hour, over a source table. Every rung of the ladder keeps the count, sum, average, minimum, maximum and last value per time bucket and per key, updates as rows arrive, and survives a restart.

A trading desk stores every tick of a few thousand symbols. One ladder gives it per-second, per-minute and per-hour volume, high, low and average price for each symbol, so a chart of the last month reads a few buckets.

CREATE ROLLUP ticks_r ON ticks KEY (sym)
  AGGREGATE (count(*) AS n, sum(qty) AS vol, min(px) AS lo,
             max(px) AS hi, avg(px) AS mid)
  RESOLUTIONS (1s, 1m, 1h);

SELECT toStartOfMinute(ts) AS minute, sym,
       sum(qty) AS vol, min(px) AS lo, max(px) AS hi
FROM ticks GROUP BY minute, sym ORDER BY minute, sym;
Available

Materialized views that update as rows arrive

A materialized view updates with every insert. Keep per-minute aggregates of access logs and query the aggregate instead of the raw lines.

One view counts 5xx responses per route and minute as the log lines arrive. Another lists the clients that request many different paths, which is a sign of scanning.

Available

Alerts in SQL

CREATE ALERT defines a rule over a SQL result with a duration, labels and annotations. Alerts go to Alertmanager or to webhooks, and system.alerts lists the firing ones.

A substation stays above its load limit for fifteen minutes, and the alert reaches the on-call engineer through Alertmanager.

02

Analytical SQL

The dialect is close to ClickHouse SQL.

Available

ASOF join

An ASOF join matches each row to the last row of another table at or before its own timestamp. The ON clause names the columns that must be equal and the one comparison of the time columns, and USING (sym, ts) says the same in short, with the time column last. The planner picks a sorted-merge or a hash algorithm, and the setting asof_join_algorithm overrides the choice.

Each trade gets the last quote at or before its own timestamp, so a report shows how far each trade was from the spread at that moment.

Available

One row per key, the newest version

ReplacingMergeTree(version) with DEDUP KEY keeps the newest row for each key, and SELECT ... FINAL reads the merged result.

Order events arrive more than once with a rising version, and the table keeps the latest status of each order.

03

Functions, types and formats

The reference pages list every function, type, format and setting. Here they are by family, with what each family is for.

340 scalar functions, by family

The reference lists 340 scalar functions, about 500 names when the ClickHouse spellings count.

  • String functions Available

    Build, cut, pad, search and split text, with UTF-8 versions of the length and case functions: concat, substring, left, right, replace, reverse, repeat, translate, position, starts_with, edit_distance and more.

  • Regular expressions Available

    Match, extract and replace with a regular expression: match, extract, extract_all, extract_groups, replace_regexp_one, replace_regexp_all, count_matches.

  • Date and time functions Available

    Bucket, shift, compare and format timestamps, all in UTC: toStartOfMinute, toStartOfHour, toStartOfDay, toStartOfYear, toStartOfInterval, date_trunc, date_diff, date_add, date_sub, toYYYYMMDD, formatDateTime, ISO weeks and Unix timestamp conversion.

  • Type conversion Available

    About 70 conversions between integers, floats, decimals, dates, date-times, strings and IP addresses, each with OrNull and OrZero variants where ClickHouse has them.

  • Math functions Available

    Arithmetic, rounding, trigonometry, logarithms, powers, number theory, and the gamma and error functions: abs, round, ceil, floor, pow, gcd, lcm, factorial and the integer division and modulo variants.

  • JSON functions Available

    Read a value, a key list or a type out of a JSON string: json_extract_string, json_extract_int, json_extract_float, json_extract_bool, json_extract_raw, json_extract_keys, json_has, json_length, json_type, is_valid_json and the simple variants.

  • URL functions Available

    Take a URL apart and encode or decode it: domain, top_level_domain, protocol, path, query_string, fragment, port, extract_url_parameter and the cut_* family.

  • Hash and encoding functions Available

    Hash a value for sampling, joins or masking, and convert between binary, hex and base64: md5, sha1, sha256, sha512, city_hash64, sip_hash64, xx_hash64, wy_hash64, hex, unhex, bin, base64_encode.

  • IP address functions Available

    IPv4 and IPv6 column types, conversion to and from text and numbers, and is_ipv4_string, is_ipv6_string.

  • Bit functions Available

    bit_and, bit_or, bit_xor, bit_not, bit_test, bit_count and shifts.

  • Array and lambda functions Available

    Transform, filter, sort and sum arrays, with lambdas written as x -> expr: arrayMap, arrayFilter, arrayExists, arraySum, arraySort, arrayConcat, arraySlice, arrayDistinct, arrayIntersect, arrayCumSum and about 25 more.

  • Map functions Available

    Map(K, V) columns with map_keys, map_values, map_concat, map_from_arrays, and the aggregates sumMap, minMap, maxMap.

  • Conditional and NULL functions Available

    coalesce, if_null, null_if, assume_not_null, is_null, greatest, least, with three-valued logic in conditions.

  • Formatting and system functions Available

    format_readable_size, format_readable_quantity, format, to_type_name, version, host_name, timezone.

  • Trained models in SQL Available

    stochasticLinearRegression and stochasticLogisticRegression train a model as an aggregate, and eval_ml_method applies it to new rows.

55 aggregate functions, by family

Beyond count, sum, avg, min, max, any, argMin and argMax, the reference lists 47 more.

  • Quantiles Available

    quantile, quantiles, median, with exact and interpolated variants of each.

  • Distinct counts and sketches Available

    uniq, uniqExact, uniqUpTo, groupBitmap, topK.

  • Statistics and tests Available

    Variance, covariance, correlation, skewness, kurtosis, entropy, linear and logistic regression, and the tests studentTTest, welchTTest, mannWhitneyUTest, kolmogorovSmirnovTest.

  • Event-sequence aggregates Available

    windowFunnel, retention, sequenceMatch, sequenceCount analyse ordered events per user or session, such as how many sessions went from product view to cart to checkout within an hour.

  • Aggregate combinators Available

    -If, -OrNull, -Array, -ForEach, -State and -Merge apply to almost every aggregate and stack, as in sumIfOrNull.

  • Aggregate state columns Available

    AggregateFunction columns store the intermediate state of an aggregate, and -State and -Merge combine states across rows and parts.

04

Getting data in

Rows reach muscles over HTTP, from Kafka, from Prometheus or from a small agent next to the source. A write is acknowledged after it is synced to disk.

Available

Kafka ingest

muscles reads Confluent Avro topics through a schema registry, creates tables from the schema and acknowledges a record after the write-ahead log is synced. It needs Kafka 4.2 or later. Amazon MSK is supported soon.

An order topic becomes a table with the columns of its Avro schema, and the finance team queries the orders as they arrive.

Available

Prometheus remote write

Prometheus, Grafana Alloy and vmagent push samples to POST /api/v1/write. The first write creates the table, and you read the samples with SQL.

A platform team sends service metrics from Prometheus and joins ninety days of them with a table of deployments to see which release raised latency.

Available

Store-and-forward agent

muscles agent runs next to the data source. It tails log files and the systemd journal, takes pushed writes on a loopback port and keeps batches on disk. It resends a batch until the server acknowledges it, and an insert token stops a resend from storing anything twice.

A depot server tails the log of its scanner gateway. When the uplink drops for an hour, the agent keeps the batches on disk and sends them in order when the link returns.

Available

Inserts with safe retries

INSERT ... VALUES and INSERT ... FORMAT accept JSONEachRow, CSV, TabSeparated, RowBinary and Native. A column you leave out takes its default. Each table remembers the last 1000 insert tokens, so a retried batch is acknowledged and stored once, also after a restart.

A gateway posts JSON lines every second. When a batch fails, it sends the same batch with the same token, and the table gains no duplicates.

05

Data that lives elsewhere

You do not have to store everything in muscles. It reads other systems and lake files in place, joins them with your tables, and it can move old data to S3.

Available

Tables that live elsewhere

CREATE EXTERNAL TABLE declares a table in another system. A SELECT reads it in place, and it joins other external tables and your stored tables with every join kind, ASOF included.

Available: Iceberg, PostgreSQL, MySQL, MariaDB, ClickHouse, Redis, Elasticsearch, Snowflake, Google Sheets.

Planned: Prometheus, Apache Solr, MongoDB, Vertica, kdb+, Cassandra, BigQuery, Databricks, Microsoft SQL Server, Oracle, Delta Lake, Apache Hive, Apache Druid, Apache Pinot, Redshift, StarRocks, InfluxDB 2, InfluxDB 3, QuestDB, QuasarDB, TDengine, Amazon Timestream.

An analyst at an online shop joins the orders in its Iceberg datalake with the customer table in PostgreSQL, from the same SQL console and without an export.

Available

Cold tier on S3

Parts older than an age you set move to S3 and stay queryable. A cold read fetches only the columns and granules the query needs.

Ninety days of shipment events stay on local disks, and older parts move to a bucket.

06

Search, vectors and language models

Text search, vector search and calls to a language model run inside SQL.

Available

Full-text search

CREATE INDEX ... TYPE fulltext indexes a string column by words. With min_gram and max_gram it also holds fragments of words, so LIKE '%fund%' can use it. hasToken finds rows by whole words and bm25Score ranks them.

Help articles are ranked by how well they match the words of a support ticket.

Available

Embeddings and vector search

Store embeddings as float arrays and rank rows with L2Distance or cosineDistance. Search is exact by default, and a TYPE vector index is available for speed.

The ten help articles closest to a customer's question, by the distance of their embeddings.

Available

Language model functions

llmClassify, llmSummarize and llmEmbed call a language model endpoint that you configure on your own network. Only administrators can use them, and the server caches results and applies limits.

Incoming support tickets are labelled refund, delivery or fault with one query.

07

Security and compliance

Who can see what, who changed what, and how to erase data.

Available

Column policies and masking

CREATE POLICY refuses, hides or hashes a column, filters rows with a predicate or embargoes recent rows, for a role or a user, per column, table or schema. One statement can keep a role out of a whole database.

Support staff query the customers table. The email column reads as a hash, and mrr, the monthly recurring revenue, is refused.

Available

Tamper-evident audit log

The opt-in audit log records who ran what. Its blocks are hash-chained, and SYSTEM VERIFY AUDIT reports the first block that does not match.

An auditor asks for proof that the log of data access was not edited, and the check returns the chain as intact.

08

Durability, storage and upgrades

What happens to your data when the disk, the process or the version changes.

Available

Upgrades keep your data

A new release reads the stored formats of earlier beta releases, and muscles migrate copies a running deployment into a new server, checks each table by digest, follows new writes and cuts over.

A depot database moves to a new server while the scanners keep sending.

Available

Replication

Replication ships parts through S3 and a Kafka commit log to a replica, together with table definitions. It is off by default, and an operator promotes a replica by hand.

A replica in a second site serves reports. If the primary fails, an operator promotes the replica.

09

Running it

Single node first, then query, ingest and data nodes, replicas and Kubernetes.

Available

Query, ingest and data nodes

A node runs as all, query, data or ingest. Query nodes send a query to the shard nodes and merge the partial results.

Ingest nodes absorb a flash-sale spike while analysts query from nodes of their own.

10

Connect your tools

Dashboards, notebooks and drivers reach muscles over HTTP.

Available

ClickHouse HTTP interface

ClickHouse drivers connect to the HTTP interface, and muscles accepts a subset of ClickHouse SQL. The interface takes the user from headers or basic auth, and reads readonly, database and query settings from the URL.

A team points its Grafana ClickHouse data source at muscles over HTTP and ports its dashboards one at a time.

Available

Python and Polars

scan_muscles reads a table as a lazy frame and pushes column selection, filters and limits to the server. write_polars writes a frame in chunks with a token per chunk, and follow yields new rows as batches.

A notebook pulls only the needed columns of a tick table and writes the cleaned frame back.

11

Tracing, console and documentation

Traces, metrics, the console and the reference pages.

Available

Tracing

muscles exports traces for queries, flushes, merges and boot over OTLP, to Jaeger or any OTLP/HTTP collector. A query trace nests the parse, plan, scan and aggregate steps.

See how long a slow dashboard query took, and whether a flush or a merge ran at the same time.

Want to try this on your own data? The first 30 days are free. See how the private beta works or write to hello@muscles.dev.