Self-hosted service
Basekick-Labs/arc avatar
Basekick-Labs/arc

Arc keeps telemetry as Parquet on storage you own and queries it with SQL

Open, SQL-native time-series database for telemetry you need to keep. 38M+ records/sec ingestion, 8M+ rows/sec queries. InfluxDB Line Protocol and Telegraf compatible. Open Parquet on your storage. Single binary. S3/Azure native. Air-gap ready. AGPL-3.0.

684 stars55 forksGoAGPL-3.0

At a glance

What is it?
Arc is a single-binary time-series database built on DuckDB that ingests InfluxDB Line Protocol, writes Apache Parquet to local disk, S3 or Azure, and offers standard SQL over the whole history. Its limits are equally concrete: AGPL-3.0 licensing and a younger ecosystem than TimescaleDB or VictoriaMetrics.
Who is it for?
Arc fits teams with heavy telemetry that must stay queryable at full resolution, who want files they can read with other tools, and who can live with AGPL-3.0 or buy an Arc Enterprise licence. It does not fit a team that cannot approve AGPL-3.0, a transactional workload that belongs in PostgreSQL, or a PromQL dependent monitoring setup.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Seven subsystems in one binary, with DuckDB underneath

Arc describes itself as a complete time-series analytical database rather than a wrapper, and the README spells out what that means. In a single binary you get the ingestion pipeline, a Parquet storage engine, a compaction system, a SQL query layer, a retention policy manager, a continuous query scheduler and the telemetry integrations.

The query engine is DuckDB. What Arc adds on top is the operational part that a pure embedded engine does not have: high-throughput writes with automatic Parquet flushing, background compaction, scheduled compute, data lifecycle management, authentication, backup and restore, and enterprise clustering.

That division of labour is the key architectural fact. You are not calling DuckDB from your own service, and you are not assembling a cluster of ingesters, a compactor and a query tier. The README is explicit that you do not bring your own ingestion, compaction or retention policies.

The Go module confirms the shape of the dependency set. Beyond DuckDB, the go.mod pulls in the AWS SDK v2 for S3, the Azure SDK for blob storage, Apache Arrow Go, Eclipse Paho for MQTT, HashiCorp Raft for clustering, robfig/cron for scheduling, spf13/viper for configuration, Fiber for the HTTP layer, and zerolog for logging. The module targets Go 1.26.0 with toolchain go1.26.9.

On throughput, the repository's own badges and README table claim 38M+ records per second ingestion and 8.42M rows per second query, benchmarked by the project on a MacBook Pro M3 Max with 12 concurrent workers and 1000-record batches. Those are the project's numbers on its own hardware, not an independent result.

Parquet files on your disk or your object store, not a proprietary format

The storage decision is the one that determines whether you can leave later, and Arc makes it in plain terms: data is stored as standard Apache Parquet, on local disk, S3, Azure, or any S3-compatible store. The README names SeaweedFS, R2 and MinIO as examples of the compatible category.

Parquet is the file format the wider data ecosystem already reads. A columnar, self-describing format means the files Arc writes are not locked behind an Arc-specific reader, and that is the practical answer to the vendor lock-in problem the README lists among the common trade-offs teams run into.

The background machinery around the files is the part worth understanding. Arc flushes to Parquet automatically as data arrives, and a background compaction system rewrites those files over time. The README names automatic Parquet storage and compaction as combined features, and the dependency set shows the machinery that supports it: klauspost/compress for compression, roaring bitmaps for indexes, and a small Arrow dependency for the columnar data path.

Retention is handled by a dedicated policy manager rather than by deleting rows, which is consistent with a Parquet layout where the natural unit of deletion is a file. Continuous queries run on a scheduler, with robfig/cron in the dependency list, and the README describes them alongside retention policies as part of the single-binary stack.

The consequence for an operator is that there are two separate things to tune: how data is written and compacted into files, and how long those files are kept. A retention policy that does not match your compaction behaviour is where storage cost surprises come from.

Line Protocol compatibility is the migration path, not a bolt-on

Arc accepts InfluxDB Line Protocol directly, which means existing Telegraf inputs can write to it without changing the collection layer. The README is careful about what compatibility means: Telegraf-compatible ingestion, so you can dual-write and validate before cutover.

The migration sequence it recommends is deliberately unglamorous. Point a small slice of ingestion at Arc, or dual-write to both systems. Compare the data and the query results over an overlapping window. Move one dashboard or workload at a time. Decommission the old database only after a full retention cycle has passed.

That last step is the one people skip. Because Arc's value proposition is keeping full-resolution history, retiring the old system before a full retention cycle has run means the comparison period never happened. A migration guide for InfluxDB and comparison pages against TimescaleDB, InfluxDB, ClickHouse and Elasticsearch are linked from the README, and the point of the dual-write step is to produce a real comparison rather than a hopeful one.

Two companion projects sit alongside the server. Arc Launchpad is a self-hosted web console for Arc instances, offering a SQL console, schema explorer, logs, monitoring, and management for tokens, retention, alerts, continuous queries and MQTT ingestion, deployable with Docker Compose. arcli is the command line, with named connections, SQL queries in table, JSON, CSV or Arrow output, line-protocol and MessagePack writes, bulk imports, and admin commands for tokens, retention, continuous queries, backups and compaction. The MessagePack support is backed by the Basekick msgpack module and the vmihailenco and hashicorp msgpack packages in go.mod.

The query surface is plain SQL, over schemas you can join

Arc's answer to proprietary query languages is that there isn't one. The README advertises window functions, CTEs, joins and analytical aggregations, and the sample queries show a two-table join between readings and device metadata, which is the shape you need once telemetry carries a device identifier you want to enrich with site or owner information.

A representative query from the README:

sql
-- Telemetry: hourly sensor summary across a full history
SELECT
  device_id,
  DATE_TRUNC('hour', timestamp) AS hour,
  AVG(value) AS average_value,
  MIN(value) AS minimum_value,
  MAX(value) AS maximum_value
FROM telemetry.sensor_readings
WHERE timestamp > NOW() - INTERVAL '30 days'
GROUP BY device_id, hour
ORDER BY hour DESC;

Two details are worth noting. The time filter uses SQL interval syntax against NOW(), and the window spans 30 days of full-resolution history rather than a downsampled rollup, which is the whole point of the Parquet-and-compaction model. The grouping is done on a truncated hour alongside the device identifier, so the result set stays small even when the scanned data is not.

Because the storage is Parquet rather than a row store, the cost profile of a query depends on how much data the filters actually touch. That is the trade-off the whole design accepts: cheaper storage and full history, in exchange for scans that are wider than an index-driven row store would give you.

Building the server: a Makefile with a CGO-dependent DuckDB tag

The repository builds with a Makefile whose default target set is small. Dependencies first:

bash
deps: ## Download Go dependencies
	$(GO) mod download
	$(GO) mod verify

Then the server binary, which is built with CGO enabled and a custom build tag, because the DuckDB engine is not a pure Go dependency:

bash
build: ## Build the binary
	$(GO) build $(GOFLAGS) -o $(BINARY_NAME) $(MAIN_PATH)

The Makefile sets GOFLAGS to include the duckdb_arrow tag and points MAIN_PATH at ./cmd/arc, so the output is a single arc binary. The cmd/ directory in the tree is where that main package lives, and the internal/, pkg/ and operations/ directories hold the rest of the server code.

Practical consequences follow from that build definition. CGO_ENABLED=1 means a C toolchain is required to compile the server, which rules out some minimal container images and cross-compilation setups that assume a static pure Go binary. The DuckDB dependency also means the binary is not trivially reproducible on a different architecture without the right libraries.

Configuration is handled by spf13/viper, and the repository ships an arc.toml file at the top level, which is the file to look at first when you need to know what the server reads for its settings.

A FIPS build variant and an opt-in Rust query engine

The Makefile carries two extra build paths that reveal where the project is heading.

The first is the FIPS 140-3 variant, built from the same source, commit and version as the standard build, with only the build tag and the Go cryptographic module selection differing. The FIPS tag enables fail-closed legacy-token verification and bakes in GODEBUG=fips140=only, using the CMVP-certified module snapshot GOFIPS140=v1.0.0. The resulting binary is named arc-fips, while the Dockerfile always names the binary arc inside the image and conveys the FIPS variant through the image tag, on the principle that FIPS is a build variant and not a version.

The second is arcx, a standalone Rust query engine that runs in process through cgo and FFI. It is opt-in. The default build stays pure Go plus DuckDB and needs no Rust toolchain, and the arcx build compiles a library from a sibling arcx checkout, with ARCX_DIR pointing at the directory, by default the sibling ../arcx, and linking it through the arcx_engine build tag. The design note referenced in the Makefile lives in the arcx repository, not in this one.

For an adopter, the practical reading is that the default build has no unusual prerequisites beyond a C toolchain, and the FIPS path is what regulated deployments would reach for. Authentication and token handling are present in the stack, and the fail-closed behaviour on legacy tokens only applies in the FIPS variant.

The Dockerfile pre-seeds DuckDB extensions so air-gapped startup works

The container build carries a comment block that explains a startup dependency, and it is worth reading before deploying to a restricted network.

Arc loads DuckDB extensions at startup, including httpfs for S3 and HTTP reads and aws for the credential-chain providers, which include the CHAIN 'web_identity' provider for IRSA. Without pre-seeding, the first run performs an INSTALL that fetches from extensions.duckdb.org. The result is that an air-gapped or egress-restricted deployment fails at startup, and everyone else pays a network round trip on first boot.

So the Dockerfile builds the image with those extensions already in the local cache, which makes the startup INSTALL and LOAD resolve against that cache instead of the network. The comment notes that the image is built from the same go.mod as the server, so the cached extension binaries stay in step with the bundled DuckDB version.

This is a small detail with a large operational footprint. The README markets Arc as air-gap ready, and the mechanism that delivers it is an image build step, not a runtime setting. If you build the binary yourself rather than using the image, you inherit the first-boot fetch behaviour and need to seed the extensions yourself. The air-gap claim and the extension pre-seeding belong to the same design decision.

The repository also ships a helm/ directory, a deploy/ directory, a Dockerfile, a .dockerignore and a scripts/ directory, so the deployment surface is broader than a single container image.

Where Arc is the wrong tool, and what the alternatives actually do

The README has a section on when Arc may not be the right choice, and it is more useful than most such sections because each option names a specific alternative and the reason.

If your workload is primarily transactional relational data and already fits comfortably in PostgreSQL, the recommendation is to evaluate TimescaleDB. That is a different architecture: a relational database with time-series features, where your existing SQL and transactional guarantees keep working. Arc, by contrast, is an analytical store built around Parquet files and DuckDB scans.

If you need a mature metrics-only replacement for Prometheus and depend on PromQL, the recommendation is VictoriaMetrics. That path keeps the Prometheus ecosystem and its query language, and avoids a database designed for full-resolution history rather than for a metrics workload.

Two further conditions are about the project rather than the workload. If your organisation cannot approve AGPL-3.0 software, the README points to Arc Enterprise's commercial licence, or to an Apache-licensed alternative. And if you need the largest established community and the lowest adoption risk, the README concedes that Arc is newer than TimescaleDB, VictoriaMetrics and QuestDB.

On licensing itself, the repository is AGPL-3.0, which for a hosted or network-accessible service has obligations that a permissive licence does not. That is the single most consequential fact for a team deciding between Arc and an Apache-licensed alternative, and it is a policy question for your legal team rather than a technical one.

On maintenance, the last push was on 2026-10-22, and the listed releases include Arc 26.09.3 on 2026-10-05, Arc 26.09.2 on 2026-10-01 and Arc 26.09.1 on 2026-08-31. The tree carries a long run of release notes files, from RELEASE_NOTES_2026.02.1.md through RELEASE_NOTES_2026.09.3.md, plus a later 2027.01.1 file, which is a sign of frequent patch-level shipping. Frequent releases mean frequent upgrade work, and each one is a chance to read a new release notes file.

Editorial conclusion

Arc fits teams with heavy telemetry that must stay queryable at full resolution, who want files they can read with other tools, and who can live with AGPL-3.0 or buy an Arc Enterprise licence. It does not fit a team that cannot approve AGPL-3.0, a transactional workload that belongs in PostgreSQL, or a PromQL dependent monitoring setup. Verify first that a dual-write of your existing Telegraf pipeline produces comparable query results, then read arc.toml and the retention settings before enabling compaction, because the storage model and the licence are the two commitments you cannot undo later.

Frequently asked questions

What storage format does Arc use for time-series data?

Arc stores data as standard Apache Parquet, on local disk, S3, Azure, or any S3-compatible store such as SeaweedFS, R2 or MinIO. Writes are flushed to Parquet automatically and a background compaction system rewrites those files.

Can Arc accept InfluxDB Line Protocol and Telegraf agents?

Yes. Arc accepts InfluxDB Line Protocol directly, so existing Telegraf inputs can write to it without changing the collection layer. The README recommends dual-writing and comparing results over an overlapping window before cutover.

What query engine does Arc use?

Arc uses DuckDB as its query engine and adds a durable ingestion and analytics layer on top, including high-throughput writes with automatic Parquet flushing, background compaction, scheduled compute, data lifecycle management, authentication, backup and restore, and enterprise clustering. Queries use standard SQL rather than a proprietary language.

Is Arc open source and under which licence?

Arc is released under AGPL-3.0. The README states that organisations unable to approve AGPL-3.0 software should use Arc Enterprise's commercial licence or choose an Apache-licensed alternative.

How do I build the Arc server binary from source?

The Makefile provides a deps target that runs go mod download and go mod verify, and a build target that compiles ./cmd/arc with the duckdb_arrow build tag and CGO enabled, producing a binary named arc. A build-fips target produces a separate arc-fips binary using the certified GOFIPS140=v1.0.0 module.

What tools ship alongside the Arc server?

Arc Launchpad is a self-hosted web console for Arc instances with a SQL console, schema explorer, logs and management for tokens, retention, alerts, continuous queries and MQTT ingestion, deployable with Docker Compose. arcli is the command line, offering named connections, SQL queries with table, JSON, CSV or Arrow output, line-protocol and MessagePack writes, bulk imports, and admin commands.

Official sources

  1. Basekick-Labs/arc on GitHub
  2. License: AGPL-3.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/basekick-labs-arc.svg)](https://hysenlabs.com/projects/basekick-labs-arc)

Was this useful?