The complete shipped feature surface, one area per section, each row linking
to the page that documents it in depth. This page is the authoritative
capability inventory: a capability appears here only when it is backed by
code and tests in the repository, and a config-gated or partial feature
carries its caveat in the row.
Tumbling, sliding, session and evicting tumbling windows; custom triggers (tumbling/sliding), CountEvictor/TimeEvictor on the evicting operator, allowed_lateness, late output tags. Evictors are not available on the aggregate window operators
Built behind CLINK_BUILD_SQL (on by default, matching what CI, the release
binaries, the runtime image and the Python wheel all build). One SQL file runs
embedded or submits to a cluster, unchanged.
Capability
Notes
Reference
DDL and catalog
CREATE TABLE ... WITH (connector=...), session or directory-persisted catalog, SHOW/DROP, EXPLAIN with row estimates, ANALYZE TABLE statistics
Projection and filtering with three-valued null semantics, expressions, aggregates, GROUP BY (including windowed), HAVING, ORDER BY / LIMIT, subqueries, DISTINCT, top-N
Generic committer (prepare at barrier, commit on global durability, recover-and-re-commit): file, Kafka, Parquet, raw S3 multipart, Postgres PREPARE TRANSACTION
Confluent Schema Registry wire format on Kafka: registry-framed Avro, Protobuf and JSON Schema values decoded to and encoded from JSON rows, schemas auto-registered from the declared columns, poison-message policy
The exactly-once protocol (barrier completion, 2PC sinks, confirmation markers, in-doubt resolution, recovery) is a TLA+ specification model-checked in CI over bounded configurations, with liveness; every campaign-found defect is a mutant TLC must refute. The engine records a protocol trace on request, and every trace the CI tests leave, plus a committed set, is model-checked as a behaviour of the specification. Proves the model, and that the recorded runs are behaviours of it, not the code in general
Change one operator's parallelism on a running job (clink rescale-op, HTTP, or the autoscaler). An operator whose edges are all keyed or parallelism-mismatched cuts over hot at one checkpoint barrier: sources do not rewind, unaffected operators keep running, key-group state repartitions onto the new subtasks. Anything ineligible, and any failed cutover, falls back to drain, replan and redeploy from the last completed checkpoint. Integer factors, declared bounds required. Whole-job rescale by role is refused for multi-operator jobs
Multi-coordinator leader election via etcd (opt-in); filesystem-backed job persistence; fencing epoch on every control frame so a superseded coordinator cannot deploy, cancel or commit
clink lint reports settings that would be accepted and then ignored, or that contradict each other, without contacting a cluster; exits non-zero on anything a submission would refuse, and shares its parsing with clink run so the two cannot disagree
Measured 1.9x to 5.3x less CPU per event than a JVM stream processor (median 2.45x, all 17 nexmark queries, five-node cluster, correctness-gated, raw per-run data published); a separate page prices it in instances, dollars and modelled CO2e
jemalloc as the process allocator: on by default in the runtime image, opt-in for source builds (CLINK_WITH_JEMALLOC=ON, Linux). Steady state: +5% throughput on a windowed query, neutral elsewhere, no memory change. Under repeated recovery (measured across 27 whole-job restarts): a glibc worker retained 3.3 GB with the job gone; jemalloc with prompt purging plus Arrow's pool routed to it (ARROW_DEFAULT_MEMORY_POOL=system) cut per-restart growth from ~14 MiB to under 1 MiB and returned the memory. Allocator retention, not a leak - measured, not inferred. The allocator in use is reported by clink_node --version and at node startup
Metrics plus lifecycle spans (submit, checkpoint, HA recovery, rescale) to any OpenTelemetry collector over OTLP/HTTP JSON; off unless --otlp-endpoint is given
clink-mcp, a Python MCP server over the diagnostic surface: checkpoint and savepoint inspection, capture and replay, lineage, queryable state, lint and EXPLAIN, as tools for any MCP client. Read-only; replay writes only to caller-named paths. Not on PyPI yet
One CLINK_FIELDS declaration per C++ type derives the byte codec (frozen layout, fixture-pinned), the Arrow schema and columnar batcher, registration defaults (channel name = type name), and a shape fingerprint that refuses a restore whose field list changed with no declared version bump
Every installed header, C symbol and SQL statement carries a 1.x tier: Stable (source-compatible for the line, held by a tracked header manifest, an append-only C symbol manifest, compile-only conformance units and a frozen SQL corpus), Evolving (changes with notice), or Internal
A compiled job/plugin binary loads on any engine build whose declared extension surface matches: the gate hashes a tracked header manifest plus the build options that surface uses, the pinned Arrow version and a toolchain identity (stdlib, sanitizers), so host-side changes do not invalidate deployed plugins. A refusal names the differing headers; an incompatible submit is refused before any plugin bytes ship; out-of-tree modules build with the packaged clink_add_job_module()
Twenty-plus sources and sinks, each documented with dependencies, factory
names, options, and SQL usage in the connector catalogue:
Kafka, Postgres (snapshot, CDC, sink), MySQL, ClickHouse, Cassandra, MongoDB,
Redis, S3 and S3 Parquet, GCS Parquet, Azure Parquet, WebHDFS Parquet,
Iceberg, Delta Lake (sink), Avro, HTTP, MQTT, NATS, Pulsar, RabbitMQ, file
and built-ins; on
Kafka, registry-framed Avro, Protobuf and JSON Schema values against a
Confluent-compatible Schema Registry.