Releases: Basekick-Labs/arc
Arc 26.06.1
Arc v26.06.1
What's Changed
- fix(mqtt): nil-guard subscriber map and disabled manager by @SAY-5 in #416
- fix(mqtt): unify nil-guard policy across both MQTT API handlers by @xe-nvdk in #418
- feat(cluster): hard query gating during replication catch-up (#392) by @xe-nvdk in #419
- fix(storage): release glibc heap pages after S3 retention/delete by @xe-nvdk in #420
- fix(delete): pass seekable file body to S3 upload for non-TLS PUT by @xe-nvdk in #423
- fix(storage): strip URL scheme from s3_endpoint before DuckDB by @xe-nvdk in #422
- fix(query): break streaming loop on Flush error so DuckDB result buffers free on client disconnect by @xe-nvdk in #424
- chore(deps): bump github.com/jackc/pgx/v5 from 5.9.0 to 5.9.2 in the go_modules group across 1 directory by @dependabot[bot] in #410
- style: gofmt query_arrow.go by @xe-nvdk in #429
- docs(readme): refresh Query benchmark table with May 2026 numbers by @xe-nvdk in #431
- docs(readme): refresh query benchmark numbers (May 2026) by @xe-nvdk in #432
- fix(query): mask bare FROM inside EXTRACT/SUBSTRING/TRIM/OVERLAY + Arrow IPC exec-time trailer by @xe-nvdk in #433
- chore(deps): bump the go_modules group across 1 directory with 3 updates by @dependabot[bot] in #430
- feat(arcx): Arc-side loader for the proprietary arcx DuckDB extension by @xe-nvdk in #434
- feat(database): wire arcx storage_root + denylist arc_partition_agg in user SQL by @xe-nvdk in #435
- fix(database): clean up orphaned DuckDB spill files on startup by @xe-nvdk in #437
- feat(query): columnar MessagePack query response endpoint (experimental) by @xe-nvdk in #438
- feat(server): support binding to a specific host/address — closes #439 by @xe-nvdk in #441
- fix(security): sandbox DuckDB user queries via enable_external_access=false + allowed_directories by @xe-nvdk in #442
- fix(security): gate pprof behind ARC_DEBUG_PPROF on a localhost listener + anchor + normalise PublicPrefixes match by @xe-nvdk in #443
- fix(security): HMAC-gate /api/v1/internal/cache/invalidate by @xe-nvdk in #444
- fix(cluster): inter-node HTTP must respect server.tls_enabled by @xe-nvdk in #445
- fix(security): validate Raft FSM manifest paths (closes GHSA-f85q-mvg8-qf37) by @xe-nvdk in #446
- fix(security): HMAC-authenticate cluster WAL replication (closes GHSA-wfgr-8x84-22q7) by @xe-nvdk in #449
- fix(pruning): wire periodic janitor for partition pruner caches by @xe-nvdk in #450
- feat(cluster-auth): Phase A — replicate API tokens via Raft FSM by @xe-nvdk in #451
- feat(cluster-auth): Phase A.1 — replicate RBAC via Raft FSM by @xe-nvdk in #458
- feat(cluster-auth): Phase A.2 Item 2 — cascade-on-delete soft cap by @xe-nvdk in #459
- fix: normalise time.Time writes to UTC across auth + tiering (closes #460) by @xe-nvdk in #461
- chore(cluster-auth): cleanup follow-ups from PR #451 (closes #452) by @xe-nvdk in #462
- feat(cluster): Pattern 2 shared-storage multi-writer (PR1a — code+tests) by @xe-nvdk in #463
- feat(cluster): Pattern 2 multi-writer PR1b — deployment + smokes + RouteWrite by @xe-nvdk in #464
- fix(test): Release buildArrowBatch builders + columns (closes #427) by @xe-nvdk in #465
- feat(metrics): arc_query_client_disconnects_total counter (closes #426) by @xe-nvdk in #466
- perf(ingest): sub-slice indexing in splitOnDelimiter (closes #354) by @xe-nvdk in #467
- docs(release-notes): add #426, #427, #354 sprint cleanup entries by @xe-nvdk in #468
- ci(release): publish to Docker Hub + bump all actions to Node-24 by @xe-nvdk in #469
- ci: remove Claude Code workflow (auto-PR-review + @claude responder) by @xe-nvdk in #470
New Contributors
Quick Start
Docker
docker run -d \
-p 8000:8000 \
-v arc-data:/app/data \
ghcr.io/basekick-labs/arc:26.06.1Debian/Ubuntu (amd64, arm64)
# Download and install
wget https://github.com/basekick-labs/arc/releases/download/v26.06.1/arc_26.06.1_amd64.deb
sudo dpkg -i arc_26.06.1_amd64.deb
# Start and enable
sudo systemctl enable arc
sudo systemctl start arc
# Check status
curl http://localhost:8000/healthRHEL/Fedora/Rocky (x86_64, aarch64)
# Download and install
wget https://github.com/basekick-labs/arc/releases/download/v26.06.1/arc-26.06.1-1.x86_64.rpm
sudo rpm -i arc-26.06.1-1.x86_64.rpm
# Start and enable
sudo systemctl enable arc
sudo systemctl start arcKubernetes (Helm)
helm install arc https://github.com/basekick-labs/arc/releases/download/v26.06.1/arc-26.06.1.tgzDownload Artifacts
| Platform | Architecture | Package |
|---|---|---|
| Docker | amd64, arm64 | ghcr.io/basekick-labs/arc:26.06.1 |
| Debian/Ubuntu | amd64 | arc_26.06.1_amd64.deb |
| Debian/Ubuntu | arm64 | arc_26.06.1_arm64.deb |
| RHEL/Fedora | x86_64 | arc-26.06.1-1.x86_64.rpm |
| RHEL/Fedora | aarch64 | arc-26.06.1-1.aarch64.rpm |
| Kubernetes | - | arc-26.06.1.tgz (Helm) |
Community
Arc 26.05.1
Highlights
Arc 26.05.1 is the Enterprise GA release. Major themes: production-ready Helm chart, peer file replication for bare-metal/edge clusters, dedicated compactor role with automatic failover, cluster TLS + shared-secret auth, and a top-to-bottom hardening pass on ingestion and the query path.
Enterprise
- Production-ready Helm chart (
helm/arc-enterprise/) — role-separated StatefulSets (writer/reader/compactor), HA bootstrap (Raft-safe), automatic failover wiring, durable-by-default WAL, fail-fast install validation, secure defaults, and quick-start preset values for shared-storage and local-storage topologies. - Peer file replication — Parquet files replicate between nodes automatically, SHA-256 verified through a Raft-backed manifest. Resumable transfers; non-leader writes forward to the Raft leader. Enables bare-metal/VM/edge deployments without shared object storage.
- Dedicated compactor role with automatic failover —
ARC_CLUSTER_ROLE=compactorruns compaction on exactly one node. Raft leader monitors and reassigns after ~30s unresponsiveness; 60s cooldown prevents cycling. - Cluster TLS + shared-secret auth — encrypted inter-node traffic across coordinator, WAL replication, shard replication, and Raft. HMAC-SHA256-signed joins with replay protection.
- Kubernetes-ready node identity — defaults to OS hostname (StatefulSet pod name). Graceful
LeaveNotifyon shutdown so peers remove the node from Raft immediately instead of waiting for heartbeat timeout. - Reader query freshness via WAL replication — readers apply replicated WAL entries to their local ArrowBuffer; ingested data is queryable on readers within milliseconds of arriving at the writer.
- Manifest-vs-storage reconciliation (anti-entropy) — periodic reconciler detects orphan manifest entries and orphan storage files. Off-by-default; report-only on first run; bounded blast radius via per-run cap, grace window, and root-walk cap.
- Dead node removal API —
DELETE /api/v1/cluster/nodes/:idremoves dead voters from Raft and the FSM. - Cluster-safe schedulers — retention, continuous queries, and DELETE endpoint all gate on
IsPrimaryWriter()per tick. Failover and demotion take effect without restart. Manifest-before-storage ordering preserved. - Batched Raft commands for compaction —
CompletionWatcherapplies all RegisterFile + DeleteFile ops for a manifest in one Raft entry. Apply latency ~200ms → ~5ms for typical 20-output manifests. - RBAC cache lifecycle —
Close()shutdown for the cleanup goroutine, bounded caches (default 10K entries each).
Deployment
- Traefik v3.6 in docker-compose examples — replaces nginx in both
deploy/docker-compose/(shared storage) anddeploy/docker-compose-local/(local storage). Routing via container labels; adding a node is one compose edit. - Deployment Patterns docs — new page comparing shared-storage vs. local-storage cluster topologies side-by-side: docs.basekick.net/arc-enterprise/deployment-patterns.
Hardening — Ingestion (26.05.1 Pre-GA)
A 4-agent staff/principal-engineer review of all three ingest paths (MessagePack columnar, MessagePack row, Line Protocol, TLE) surfaced and fixed five criticals. Sustained-load benchmarks: p99 latency 3.68ms → 3.13ms (~17% better), ~19M rec/s on MsgPack columnar, 0% errors over 60s.
- Multi-hour flush atomicity — manifest now updates only after all hour buckets have written successfully (collect-then-register).
- Graceful-shutdown panic eliminated —
ArrowBuffer.Close()no longer races writers on a closed channel. - Schema-evolution corruption under concurrent writes eliminated — bounded retry loop returns typed
ingest.ErrSchemaChurnExceeded(HTTP 503) instead of silently committing schema-mixed buffers. - WAL backpressure no longer masquerades as durability — typed
wal.ErrWALDroppedsentinel with separatetotal_wal_droppedcounter; cluster-replication receivers tolerate the error instead of diverging followers. - Performance: cached column signatures (zero-alloc hot-path schema check), pre-built parquet writer properties, single-pass sort permutation reuse, value-typed merge structs.
Hardening — Query Path (26.05.1 Pre-GA)
A second 4-agent review on the read path surfaced six critical-path issues. ClickBench-hits regression budget held: ~3% on a 99.9M-row aggregate.
- Expanded SQL denylist — gates
ATTACH/DETACH/COPY/EXPORT/IMPORT/PRAGMA/SET/RESET/LOAD/INSTALL/CALLon the read-only query API. Comment-strip and string-literal masking closeDROP /* */ TABLE xandSELECT 'DROP TABLE x'bypass shapes. x-arc-databaseheader validation + universalread_parquetpath quoting — everyread_parquet('PATH', ...)site now routes through a single-source-of-truth quoting helper.- Direct
read_parquet()in user SQL rejected — prevents bypass of the database/measurement RBAC pair-check. - Streaming-response error semantics —
streamTypedJSONandstreamArrowJSONnow propagate Scan failures andctx.Err(); partial streams are no longer markedComplete. - Parallel-partition partial failure surfaced as request error — any errored partition fails the whole request with HTTP 500 (was: returned surviving rows as
success: true). - Arrow IPC streaming memory bound — explicit per-batch
Release()instead of accumulateddefer; constant per-batch memory restored.
Security
- Write endpoints now require write-tier auth — five ingest endpoints (
/api/v1/write/msgpack,/write,/api/v2/write,/api/v1/write/line-protocol,/api/v1/write/tle) and four bulk-import endpoints lacked explicit write-tier auth. All now useauth.RequireWrite; imports useauth.RequireAdmin. - Gzip + zstd decompression-bomb fixes — line-protocol and TLE handlers now apply the same hard 100MB cap that msgpack already enforced. Bound is enforced during decoding so a 28KB → 256MB zstd bomb is rejected with bounded allocation.
- Symmetric
maxSizecap on uncompressed branch — closes the uncompressed-OOM vector left open after the gzip fix. - Defensive body copy — LP and TLE handlers no longer hand fasthttp-owned slices to async parsers; regression test pins the no-aliasing invariant.
- Cluster-safe DELETE — readers reject deletes with 503 before any storage scan; database/measurement inputs validated against
..,/,\. - Directory permissions 0700 — auth DB, CQ definitions, retention policies, Raft state, telemetry, import output. Existing deployments retain prior permissions; operators may
chmod 700manually. - SQL escaping defense-in-depth — DuckDB
SET memory_limitand compactionORDER BYsort keys.
Deprecations
?p=tokenquery parameter authentication (InfluxDB 1.x compat) is now deprecated. Tokens in URLs leak through reverse proxies / load balancers / access logs. Continues to work; first use logs a one-time warning. Migrate toAuthorization: Bearer <token>.
Bug Fixes
- WAL filename rotation collision — second-precision filenames could collide on rapid rotation. Now nanosecond-precision (
arc-YYYYMMDD_HHMMSS.000000000.wal). - Query registry reports 0 row count for Arrow-path queries — Arrow streams asynchronously; registry now receives real counts via
onComplete/onFail/onTimeoutcallbacks. - Low-volume measurements starved of age-based flushes under load —
periodicFlushno longer extends the timer when a new buffer's deadline is later than the current one. - Memory not released after delete/retention —
ClearHTTPCache()+ debounceddebug.FreeOSMemory()after every delete and retention run; delete COPY queries now constrainROW_GROUP_SIZE. - Writer-only schedulers skipped all ticks without failover enabled —
Coordinator.IsPrimaryWriter()falls back toRole == RoleWriterwhen no failover manager is configured. Fixes retention and CQs silently no-op'ing on default cluster config. - CQ not scheduled after API creation —
handleCreatenow callsscheduler.StartJobDirect; previously required a restart. - RBAC goroutine leak —
RBACManager.Close()added; registered with the shutdown coordinator. - Row-format MessagePack flush hardening — regression coverage +
arc_buffer_flush_failures_totalPrometheus counter for visibility.
Dependencies
| Package | From | To |
|---|---|---|
| DuckDB Go binding | v2.5.5 (DuckDB 1.4.4) | v2.10501.0 (DuckDB 1.5.1) |
aws-sdk-go-v2 core |
1.40 | 1.41.5 |
aws-sdk-go-v2/service/s3 |
1.92 | 1.99 |
smithy-go |
1.23 | 1.24 |
S3 DNS-timeout retries are now automatic; non-existent AWS profile no longer fails config load.
How to Update
Docker:
docker pull ghcr.io/basekick-labs/arc:26.05.1Debian/Ubuntu:
wget https://github.com/basekick-labs/arc/releases/download/v26.05.1/arc_26.05.1_amd64.deb
sudo dpkg -i arc_26.05.1_amd64.debRHEL/Fedora:
wget https://github.com/basekick-labs/arc/releases/download/v26.05.1/arc-26.05.1-1.x86_64.rpm
sudo rpm -i arc-26.05.1-1.x86_64.rpmHelm:
helm upgrade arc https://github.com/basekick-labs/arc/releases/download/v26.05.1/arc-26.05.1.tgzFull release notes (long-form, with config tables and per-fix detail): RELEASE_NOTES_2026.05.1.md
What's Changed
- fix(delete,retention): clear DuckDB cache and free OS memory after execution by @xe-nvdk in #372
- chore(deps): bump github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream from 1.7.3 to 1.7.8 in the go_modules group across 0 directory by @dependabot[bot] in https://github.com/Basekick-Labs/a...
Arc 26.04.1
Performance
- Native DuckDB Arrow query path — bypasses
database/sqlrow scanning entirely; results read as Arrow record batches directly from DuckDB.- JSON endpoint: +59% (1.43M → 2.28M rows/sec)
- Arrow IPC endpoint: +157% (2.45M → 6.29M rows/sec)
- Tested on 1.88B row dataset
- Typed JSON streaming serialization — zero-allocation streaming writer replaces
json.Marshal. ~8KB constant memory regardless of result size. 2.3x faster serialization, 99.9% fewer allocations - Basekick-Labs/msgpack v6 — lower-allocation decode path
- Sustained throughput: 16.78M → 18.23M rec/s
- 60s degradation: 22% → 13%
Security
⚠️ Update recommended. See RBAC fix below.
- RBAC write permission bypass fixed —
CheckWritePermissionsused wrong context key ("token"vs"token_info"), silently bypassing all RBAC write restrictions. Update immediately if running RBAC. - Token privilege escalation fixed — Token create/update API now validates permission strings
RequireAdminmiddleware added to all mutating endpoints (continuous queries, delete, retention policies, compaction, scheduler)- WAL reader OOM — payload length now validated before allocation on corrupt WAL
- MessagePack decoder data race — non-atomic
totalDecoded/totalErrorscounters fixed - Ingestion buffer
Close()race — iterator/lock race during shutdown fixed - MQTT
/statsand/healthendpoints now require authentication ARC_DATABASE_MEMORY_LIMITSQL injection — value now validated against allowlist before being passed to DuckDBSET- Delete WHERE clause hardened — blocks
UNION,SELECT,CREATE,COPY,ATTACH,LOAD,PRAGMA,CALL,SET - Temp directory permissions — changed from
0755to0700
New Features
- Automatic compaction deduplication — last-write-wins on identical tag+timestamp combinations. Zero config, zero overhead when no duplicates exist. Tag columns auto-detected from
arc:tagsParquet metadata written at ingestion time - Decimal128 type support — native Parquet
DECIMALfor financial/scientific precision. Configure viaARC_INGEST_DECIMAL_COLUMNS(format:measurement:col=precision,scale) - S3 path prefix (
ARC_STORAGE_S3_PREFIX) — prepends a prefix to all S3 operations for shared-bucket multi-tenant isolation - Bootstrap token (
ARC_AUTH_BOOTSTRAP_TOKEN) — set a known admin token at deploy time instead of catching a random one from startup logs - Auth recovery (
ARC_AUTH_FORCE_BOOTSTRAP) — adds aarc-recoveryadmin token without removing existing tokens - WAL drops metric —
arc_wal_dropped_entries_totalPrometheus counter for real-time alerting. Buffer size configurable viaARC_WAL_BUFFER_SIZE - Slow query logging — configurable threshold via
ARC_QUERY_SLOW_QUERY_THRESHOLD_MS. Logs SQL, execution time, row count, token name at WARN level. Prometheus counter:arc_slow_queries_total
Bug Fixes
- Hourly compaction race with active ingestion — compaction now enforces a 1-hour minimum file age before compacting. Default config corrected:
hourly_min_age_hours = 1,hourly_min_files = 10 - CQ scheduler reload on update — continuous query updates now immediately reload the scheduler. Previously required a restart
- Atomic CQ execution recording — execution state +
last_processed_timenow wrapped in a SQLite transaction, preventing duplicate or missing windows on failure - S3 delete-rewrite OOM — now streams through temp file instead of loading entire Parquet files into memory
- Backup restore OOM — same fix: large Parquet files streamed instead of fully loaded
- Token expiration display — non-expiring tokens no longer show as "Expired". Changed
ExpiresAtfromtime.Timeto*time.Time - Auth bootstrap TOCTOU race — initial admin token creation replaced with
INSERT ... WHERE NOT EXISTS(safe under concurrent startup) - Helm: deployment strategy defaults to
Recreate— fixesRollingUpdatedeadlock with single replica +ReadWriteOncePVC
Dependencies
| Package | From | To | Notable fixes |
|---|---|---|---|
DuckDB (duckdb-go) |
1.4.3 | 1.4.4 | Parquet UTF-8 string stats tolerance, Arrow string view pushdown correctness, mode() use-after-free, S3 credential secure clear |
| Arrow Go | v18.4.1 | v18.5.2 | Large string Parquet write corruption fix, decompression regression fix, GC pressure reduction |
| gRPC | 1.79.1 | 1.79.3 | Authorization bypass fix for malformed :path headers missing leading slash |
How to Update
Docker:
docker pull ghcr.io/basekick-labs/arc:26.04.1Helm:
helm upgrade arc https://github.com/Basekick-Labs/arc/releases/download/v26.04.1/arc-26.04.1.tgzConfig check: If running the default arc.toml, update your hourly compaction settings:
[compaction]
hourly_min_age_hours = 1 # was 0
hourly_min_files = 10 # was 5What's Changed
- feat(auth): add ARC_AUTH_BOOTSTRAP_TOKEN and ARC_AUTH_FORCE_BOOTSTRAP for predictable deployments and recovery by @xe-nvdk in #360
- fix(helm): default deployment strategy to Recreate for RWO volume compatibility by @xe-nvdk in #361
- fix(security): restrict temp file permissions and validate memory_limit by @xe-nvdk in #368
Full Changelog: v26.03.2...v26.04.1
Arc 26.03.2
Bug Fix
Compaction Batch Filename Collision — Critical Data Loss
When a partition accumulated more than 30 files, the compaction system split them into sequential batches of 30. Each batch generated its output filename using second-precision timestamps (YYYYMMDD_HHMMSS), causing all batches completing within the same second to produce identical filenames. Each batch overwrote the previous batch's compacted file, destroying up to 84% of ingested data.
Impact: Any measurement with more than 30 files per hour partition was affected. This is common with max_buffer_age_ms below 1000ms or high-frequency ingestion pipelines. Telegraf default configurations with multiple field groups were particularly susceptible.
Fix: Added nanosecond precision to compacted output filenames, guaranteeing uniqueness across sequential batches. Updated extractNewestFileTime to parse both old and new filename formats.
Upgrade: Drop-in replacement for v26.03.1. No configuration changes required.
What's Changed
- perf(api): typed JSON streaming serialization for query responses by @xe-nvdk in #253
- perf(api): DuckDB native Arrow query path by @xe-nvdk in #254
- feat(observability): add slow query logging by @xe-nvdk in #255
- fix(auth): token expiration display for non-expiring tokens by @xe-nvdk in #256
- feat(deps): upgrade DuckDB 1.4.4, Arrow Go v18.5.2 by @xe-nvdk in #259
- feat(storage): add S3 path prefix support by @xe-nvdk in #261
- chore: apply gofmt -s across codebase by @xe-nvdk in #262
- chore: apply gofmt -s to all remaining directories (scripts, pkg, ben… by @xe-nvdk in #263
- chore: suppress CodeQL false positives by @xe-nvdk in #264
- feat(bench): add ClickHouse targets to sustained_bench by @xe-nvdk in #265
- refactor(bench): deduplicate ClickHouse data generators by @xe-nvdk in #266
- feat(bench): add InfluxDB 3 target to sustained_bench by @xe-nvdk in #267
- Feat/simdutf validation by @xe-nvdk in #268
- chore(deps): bump google.golang.org/grpc from 1.79.1 to 1.79.3 in the go_modules group across 1 directory by @dependabot[bot] in #269
- feat(wal): expose DroppedEntries metric and configurable BufferSize by @xe-nvdk in #270
- fix(security): auth, SQL injection, resource leaks across 4 subsystems by @xe-nvdk in #271
- fix(storage): local backend bugs, optimizations, and streaming restore by @xe-nvdk in #272
- fix(ingest): remove useless UTF-8 bulk pre-validation from msgpack path by @xe-nvdk in #273
- feat(compaction): automatic deduplication using Parquet tag metadata by @xe-nvdk in #274
- feat(ingest): native Decimal128 type support (#245) by @xe-nvdk in #276
- fix(compaction): prevent hourly tier race condition with active ingestion by @xe-nvdk in #279
- fix: address 9 critical findings from pre-release security audit by @xe-nvdk in #356
- fix(compaction): batch filename collision causes up to 84% data loss by @xe-nvdk in #358
Full Changelog: v26.03.1...v26.03.2
Arc 26.03.1
Release Arc 2026.03.1
See RELEASE_NOTES_2026.03.1.md for full details.
Highlights
New Features:
- Backup & Restore API (async, selective restore, all storage backends)
- Line Protocol Bulk Import (
POST /api/v1/import/lp) — one-command InfluxDB migration - TLE (Two-Line Element) Ingestion & Import — native satellite orbital data support
Bug Fixes:
- Null handling in Line Protocol ingestion — missing fields stored as
0instead ofNULL(#202) - Stale cache after compaction causes 404 errors (#204)
- Distributed cache invalidation for enterprise clustering (#204, #206)
- Generic query error messages — now returns actual DuckDB errors (#207)
time_bucket/date_truncreturning per-second rows instead of buckets (#212)- WAL recovery after flush failure replays already-flushed data (#218)
- Self-adjusting flush timer (#142)
- MQTT
CleanSessionnow configurable, defaults tofalse(#239) - Delete API partial failure reporting — HTTP 207 with
failed_files(#235) - Replication Prometheus metrics and sequence gap detection (#237)
- Orphaned hot file cleanup after tiering migration (#236)
- Compaction manifest cleanup leaves orphaned files (#240)
- Unified
cache_httpfsTTLs and scaled cache sizes (#214)
Code Quality:
- Security: database name validation on all write endpoints (path traversal prevention)
- Security: backup restore file permissions fixed to
0600 - Fix: scheduler goroutine leak, MQTT subscription TOCTOU race, cluster router unbounded map growth
- Fix: LP
precisionparameter now honored (was silently ignored) - Performance: pooled gzip decompression, single-pass LP unescape, single-pass SQL safety regex
- Cleanup: import handler and LP parser deduplication
Infrastructure:
- Go 1.26 (Green Tea GC, 30% faster cgo, 2x faster
io.ReadAll)
Quick Start
Docker
docker run -d \
-p 8000:8000 \
-v arc-data:/app/data \
ghcr.io/basekick-labs/arc:26.03.1Debian/Ubuntu (amd64, arm64)
wget https://github.com/basekick-labs/arc/releases/download/v26.03.1/arc_26.03.1_amd64.deb
sudo dpkg -i arc_26.03.1_amd64.deb
sudo systemctl enable arc
sudo systemctl start arc
curl http://localhost:8000/healthRHEL/Fedora/Rocky (x86_64, aarch64)
wget https://github.com/basekick-labs/arc/releases/download/v26.03.1/arc-26.03.1-1.x86_64.rpm
sudo rpm -i arc-26.03.1-1.x86_64.rpm
sudo systemctl enable arc
sudo systemctl start arcKubernetes (Helm)
helm install arc https://github.com/basekick-labs/arc/releases/download/v26.03.1/arc-26.03.1.tgzDownload Artifacts
| Platform | Architecture | Package |
|---|---|---|
| Docker | amd64, arm64 | ghcr.io/basekick-labs/arc:26.03.1 |
| Debian/Ubuntu | amd64 | arc_26.03.1_amd64.deb |
| Debian/Ubuntu | arm64 | arc_26.03.1_arm64.deb |
| RHEL/Fedora | x86_64 | arc-26.03.1-1.x86_64.rpm |
| RHEL/Fedora | aarch64 | arc-26.03.1-1.aarch64.rpm |
| Kubernetes | - | arc-26.03.1.tgz (Helm) |
What's Changed
- fix(ingest): preserve null values for missing fields in line protocol… by @xe-nvdk in #203
- fix(compaction): invalidate caches after compaction to prevent 404 er… by @xe-nvdk in #205
- feat(compaction): distributed cache invalidation for enterprise clustering by @xe-nvdk in #206
- fix(api): return detailed DuckDB error messages in query responses by @xe-nvdk in #208
- feat(api): add Line Protocol bulk import endpoint for InfluxDB migration by @xe-nvdk in #209
- feat(api): add TLE ingestion and import for satellite orbital data by @xe-nvdk in #210
- perf(ingest): optimize TLE hot path with typed columnar bypass by @xe-nvdk in #211
- fix(query): use DuckDB integer division in time_bucket/date_trunc rewrites by @xe-nvdk in #213
- fix(query): unify cache_httpfs TTLs with s3_cache_ttl_seconds by @xe-nvdk in #215
- fix(query): unify cache_httpfs TTLs with s3_cache_ttl_seconds (#214) by @xe-nvdk in #216
- chore: upgrade to Go 1.26 by @xe-nvdk in #217
- fix(wal): purge old WAL files before recovery on flush failure by @xe-nvdk in #219
- fix(ingest): replace fixed ticker with self-adjusting timer for age-b… by @xe-nvdk in #222
- fix: consolidate compaction schedulers to prevent daily tier starvation by @xe-nvdk in #221
- Revert "fix: consolidate compaction schedulers to prevent daily tier starvation" by @xe-nvdk in #223
- fix(compaction): prevent orphaned files from manifest cleanup bugs by @xe-nvdk in #241
- feat(tiering): add orphaned hot file reconciliation after migration by @xe-nvdk in #242
- fix(tiering): log warning when hot backend unavailable for reconcilia… by @xe-nvdk in #244
- feat(replication): add Prometheus metrics and sequence gap detection by @xe-nvdk in #243
- fix(mqtt): make CleanSession configurable, default to false (#239) by @xe-nvdk in #247
- fix(api): report partial failure in delete response (#235) by @xe-nvdk in #248
- chore(deps): bump github.com/gofiber/fiber/v2 from 2.52.11 to 2.52.12 in the go_modules group across 1 directory by @dependabot[bot] in #250
- fix(quality): 26.03.1 code review — security, correctness, and elegance by @xe-nvdk in #251
- perf(api): replace regex with byte-loop in isValidDatabaseName() by @xe-nvdk in #252
Full Changelog: v26.02.2...v26.03.1
Arc 26.02.2
Release Arc 2026.02.2
See RELEASE_NOTES_2026.02.2.md for full details.
Highlights
New Features:
- Bulk Import API (CSV & Parquet)
Enterprise Features:
- Query Governance (Rate Limiting & Quotas)
- Audit Logging
- Automatic Writer Failover (< 30s RTO)
- Cluster-Wide Core Limit Enforcement
- Long-Running Query Management
- Tiered Storage: Daily-Compacted-Only Migration Gate
Bug Fixes:
- WAL Periodic Recovery Causes 2x Data Duplication (#199)
- S3 Flush Hang: Workers Block Forever on Slow/Unresponsive Storage (#197)
- Query Returns HTTP 500 for Measurements With No Data (#198)
- Daily Compaction Blocked for Backfilled Data (#187)
- HTTP Write Timeout vs Query Timeout Mismatch (#185)
Improvements:
- LIKE Query Predicate Optimization (12.6% faster on ClickBench Q23)
- Per-Database Compaction (#184)
Quick Start
Docker
docker run -d \
-p 8000:8000 \
-v arc-data:/app/data \
ghcr.io/basekick-labs/arc:26.02.2Debian/Ubuntu (amd64, arm64)
# Download and install
wget https://github.com/basekick-labs/arc/releases/download/v26.02.2/arc_26.02.2_amd64.deb
sudo dpkg -i arc_26.02.2_amd64.deb
# Start and enable
sudo systemctl enable arc
sudo systemctl start arc
# Check status
curl http://localhost:8000/healthRHEL/Fedora/Rocky (x86_64, aarch64)
# Download and install
wget https://github.com/basekick-labs/arc/releases/download/v26.02.2/arc-26.02.2-1.x86_64.rpm
sudo rpm -i arc-26.02.2-1.x86_64.rpm
# Start and enable
sudo systemctl enable arc
sudo systemctl start arcKubernetes (Helm)
helm install arc https://github.com/basekick-labs/arc/releases/download/v26.02.2/arc-26.02.2.tgzDownload Artifacts
| Platform | Architecture | Package |
|---|---|---|
| Docker | amd64, arm64 | ghcr.io/basekick-labs/arc:26.02.2 |
| Debian/Ubuntu | amd64 | arc_26.02.2_amd64.deb |
| Debian/Ubuntu | arm64 | arc_26.02.2_arm64.deb |
| RHEL/Fedora | x86_64 | arc-26.02.2-1.x86_64.rpm |
| RHEL/Fedora | aarch64 | arc-26.02.2-1.aarch64.rpm |
| Kubernetes | - | arc-26.02.2.tgz (Helm) |
What's Changed
- release: Arc v26.02.1 by @xe-nvdk in #175
- Feat/enterprise audit logging by @xe-nvdk in #176
- feat(tiering): only migrate daily-compacted files to cold tier by @xe-nvdk in #177
- fix(audit): SQLite vacuum to prevent file bloat by @xe-nvdk in #178
- feat(cluster): automatic writer failover with <30s RTO by @xe-nvdk in #179
- fix(security): harden tiering API auth, license gating, and path traversal by @xe-nvdk in #180
- Feat/backup restore by @xe-nvdk in #181
- feat(query): optimize LIKE queries by reordering WHERE predicates by @xe-nvdk in #182
- fix(memory): optimize ingestion memory usage by @xe-nvdk in #183
- fix(compaction): bypass file age check for old partitions (#187) by @xe-nvdk in #188
- fix(config): auto-sync HTTP write timeout with query timeout (#185) by @xe-nvdk in #189
- chore(deps): bump github.com/gofiber/fiber/v2 from 2.52.10 to 2.52.11 in the go_modules group across 1 directory by @dependabot[bot] in #190
- feat(governance): per-token query rate limiting & quotas by @xe-nvdk in #191
- feat(query-mgmt): add long-running query management (Enterprise) by @xe-nvdk in #193
- feat(query-mgmt): add long-running query management (Enterprise) by @xe-nvdk in #194
- feat(compaction): add per-database compaction support (#184) by @xe-nvdk in #195
- fix(wal): prevent data duplication from periodic WAL recovery by @khalid244 in #199
- fix(wal): two-mode periodic maintenance to prevent data duplication by @xe-nvdk in #200
- Fix S3 flush hang: add timeout and context cancellation to storage writes by @khalid244 in #197
- Fix query handler to return empty result for measurements with no data by @khalid244 in #198
New Contributors
- @dependabot[bot] made their first contribution in #190
Full Changelog: v26.02.1...v26.02.2
Arc 26.02.1
Arc 26.02.1 Release Summary
Quick Start
Docker
docker run -d \
-p 8000:8000 \
-v arc-data:/app/data \
ghcr.io/basekick-labs/arc:26.02.1Debian/Ubuntu (amd64, arm64)
# Download and install
wget https://github.com/basekick-labs/arc/releases/download/v26.02.1/arc_26.02.1_amd64.deb
sudo dpkg -i arc_26.02.1_amd64.deb
# Start and enable
sudo systemctl enable arc
sudo systemctl start arc
# Check status
curl http://localhost:8000/healthRHEL/Fedora/Rocky (x86_64, aarch64)
# Download and install
wget https://github.com/basekick-labs/arc/releases/download/v26.02.1/arc-26.02.1-1.x86_64.rpm
sudo rpm -i arc-26.02.1-1.x86_64.rpm
# Start and enable
sudo systemctl enable arc
sudo systemctl start arcKubernetes (Helm)
helm install arc https://github.com/basekick-labs/arc/releases/download/v26.02.1/arc-26.02.1.tgzNew Features
InfluxDB Client Compatibility
Arc's Line Protocol endpoints now use the same paths as InfluxDB, enabling drop-in compatibility with all official InfluxDB client libraries (Go, Python, JavaScript, Java, C#, PHP, Ruby, Telegraf, Node-RED). Point your existing InfluxDB clients at Arc - no code changes required.
MQTT Ingestion Support
Native MQTT subscription for IoT and edge data ingestion. Subscribe to MQTT topics with wildcard support, dynamic subscription management via REST API, TLS/SSL connections, auto-reconnect, and per-subscription monitoring. Passwords encrypted at rest, subscriptions auto-start on server restart.
S3 File Caching (Optional)
In-memory caching of S3 Parquet files via DuckDB's cache_httpfs extension. Improves query performance 5-10x for workloads with repeated file access (CTEs, subqueries, Grafana dashboards). Opt-in feature, disabled by default.
Contributed by @khalid244
Relative Time Expression Support
Queries using NOW() - INTERVAL now benefit from partition pruning. Previously only literal timestamps worked. Now expressions like time > NOW() - INTERVAL '20 days' properly prune to relevant partitions, dramatically reducing query times.
Bug Fixes
- Control characters in measurement names - Fixed S3 failures caused by invalid characters in measurement names
- Missing S3 partitions - Queries no longer fail when time range includes non-existent partitions (day-level file verification contributed by @khalid244)
- Server timeout config ignored - Now respects configured read/write timeout values
- Large payload rejection - Fixed 413 errors on payloads >4MB
- Timestamp timezone inconsistency - All timestamps now normalized to UTC
- Azure SSL errors on Linux - Fixed certificate validation issues (contributed by @schotime)
- Compaction filename timezones - Files now use UTC consistently (contributed by @schotime)
- S3 subprocess config - Fixed compaction failures on S3-compatible storage (Hetzner, MinIO)
- Non-UTF8 data - Invalid UTF-8 automatically sanitized during ingestion
- Nanosecond timestamps - MessagePack now correctly handles nanosecond precision
- Multi-line query parsing - WHERE clause extraction now works across newlines (contributed by @khalid244)
- String literals with SQL keywords - Partition pruning no longer breaks on embedded keywords
- Buffer flush timing - Age-based flushes now fire closer to configured intervals under high load
- Arrow writer panic - Fixed crash during high-concurrency writes with schema evolution
- Empty directories - Cleaned up after daily compaction
- Compactor OOM/segfaults - Streaming I/O, memory limit passthrough, file batching, adaptive splitting
- Orphaned temp directories - Cleaned up on startup and after subprocess completion
- Compaction data duplication - Manifest-based tracking prevents re-compaction after crashes (contributed by @khalid244)
- WAL S3 recovery - Startup and periodic recovery from transient S3 failures (contributed by @khalid244)
- Tiered storage routing - X-Arc-Database header now queries cold tier data
- Retention policies - Now work with S3/Azure storage backends
- Query timeout - Prevents indefinite hangs when S3 disconnects mid-query (contributed by @khalid244)
Improvements
- Configurable server timeouts - Idle and shutdown timeouts now configurable
- Automatic time function optimization - time_bucket() and date_trunc() rewritten to epoch arithmetic (2-2.5x faster GROUP BY)
- Parallel partition scanning - Multi-partition queries execute concurrently (2-4x speedup)
- Two-stage distributed aggregation - Cross-shard aggregations use scatter-gather (5-20x speedup, Enterprise only)
- DuckDB query optimizations - Metadata caching, prefetching, insertion order preservation (18-24% faster aggregations) (SET GLOBAL fix contributed by @khalid244)
- Regex-to-string optimization - URL domain extraction rewritten to native functions (2x+ faster)
- Database header optimization - x-arc-database header skips regex parsing (4-17% faster queries)
- MQTT auto-generated client ID - Prevents collisions when running multiple instances
Security
Token hashing uses bcrypt (cost 10) with SHA256-based prefixes for O(1) lookups. Legacy SHA256 tokens continue to work for backward compatibility.
Breaking Changes
Line Protocol endpoint paths renamed to match InfluxDB API:
/api/v1/write→/write/api/v1/write/influxdb→/api/v2/write
Update client configurations. InfluxDB client libraries work unchanged with new paths.
Upgrade Notes
- MQTT feature disabled by default. Enable with
mqtt.enabled = true - Empty directory cleanup is automatic for new compaction runs only
- Existing empty directories from previous runs not automatically cleaned
What's Changed
- Feature/mqtt ingestion by @xe-nvdk in #91
- fix: Clean up empty directories after daily compaction by @xe-nvdk in #95
- fix: Support relative time expressions in partition pruning by @xe-nvdk in #96
- Feature/time bucket optimization by @xe-nvdk in #97
- feat: Add date_trunc() to epoch optimization for 2.5x faster GROUP BY by @xe-nvdk in #98
- perf: Add fast-path checks to time function rewrites by @xe-nvdk in #99
- fix: Add AzureTransportOptionType so that curl can be used when querying due to CA certificates error by @schotime in #92
- feat(enterprise): Add license-gated CQ and retention schedulers by @xe-nvdk in #100
- feat(enterprise): Add RBAC with security hardening by @xe-nvdk in #101
- fix(compaction): Resolve OOM and segfaults with large datasets by @xe-nvdk in #103
- fix: Buffer flush bug and Arrow endpoint SQL cache by @xe-nvdk in #104
- chore: Upgrade DuckDB to 1.4.3 and fix RBAC tests by @xe-nvdk in #105
- Fix/compaction batch race condition by @xe-nvdk in #106
- Perf/query optimization by @xe-nvdk in #107
- perf: Add x-arc-database header support for query optimization by @xe-nvdk in #108
- perf: Optimize header-based query parsing with fast paths by @xe-nvdk in #109
- feat(cluster): Add Phase 2 enterprise clustering foundation by @xe-nvdk in #110
- feat(cluster): Add Phase 3 cluster routing and WAL replication by @xe-nvdk in #111
- feat(cluster): Add Phase 4 multi-writer sharding foundation by @xe-nvdk in #112
- fix(wal): Prevent integer overflow in payload allocation by @xe-nvdk in #114
- feat(api): InfluxDB-compatible endpoints for drop-in client migration by @xe-nvdk in #115
- fix(auth): Add CodeQL suppression comments for SHA256 false positives by @xe-nvdk in #116
- docs: Fix MQTT configuration examples in release notes by @xe-nvdk in #117
- fix(api): Apply MaxPayloadSize config to Fiber BodyLimit by @xe-nvdk in #118
- feat(query): Parallel partition scanning and two-stage distributed aggregation by @xe-nvdk in #119
- feat(query): Add regex-to-string function rewriter for 2.2x speedup by @xe-nvdk in #120
- feat(api): Add REGEXP_EXTRACT to string function rewriter by @xe-nvdk in #121
- fix(api): Validate measurement names to prevent S3 XML parsing errors by @xe-nvdk in #124
- fix(pruning): Filter non-existent S3/Azure partitions before query execution by @xe-nvdk in #127
- fix(config): Use configured server read/write timeout values by @xe-nvdk in #128
- feat(config): Add server idle_timeout and shutdown_timeout config options by @xe-nvdk in #129
- fix: Ensure UTC dates for compaction filenames by @schotime in #132
- Fix/s3 subprocess credentials by @xe-nvdk in #135
- fix(ingest): prevent panic during high-concurrency writ...
Arc v26.01.2
Arc v26.01.2
Bugfix release addressing Azure Blob Storage backend issues and authentication configuration.
Bug Fixes
Azure Blob Storage Backend
- Fix queries failing with Azure backend - Queries were incorrectly using local filesystem paths (
./data/...) instead of Azure blob paths (azure://...) when using Azure Blob Storage as the storage backend. - Fix compaction subprocess Azure authentication - Compaction subprocess was failing with "DefaultAzureCredential: failed to acquire token" because credentials weren't being passed to the subprocess. Now passes
AZURE_STORAGE_KEYvia environment variable.
Configuration
- Authentication enabled by default -
auth.enabledis nowtrueby default inarc.tomlfor improved security out of the box.
Files Changed
internal/api/query.go- Add Azure case togetStoragePath()internal/database/duckdb.go- AddconfigureAzureAccess()for DuckDB azure extensioninternal/compaction/manager.go- Pass Azure credentials to subprocess via env varinternal/compaction/subprocess.go- Read Azure credentials from env varinternal/storage/azure.go- AddGetAccountKey()methodarc.toml- Setauth.enabled = trueby default
Upgrade Notes
- If you were relying on authentication being disabled by default, you'll need to explicitly set
auth.enabled = falsein yourarc.toml.
Arc 26.01.1
Arc 2026.01.1 Release Notes
New Features
Official Python SDK
The official Python SDK for Arc is now available on PyPI as arc-tsdb-client.
Installation:
pip install arc-tsdb-client
# With DataFrame support
pip install arc-tsdb-client[pandas] # pandas
pip install arc-tsdb-client[polars] # polars
pip install arc-tsdb-client[all] # all optional dependenciesKey features:
- High-performance MessagePack columnar ingestion
- Query support with JSON, Arrow IPC, pandas, polars, and PyArrow responses
- Full async API with httpx
- Buffered writes with automatic batching (size and time thresholds)
- Complete management API (retention policies, continuous queries, delete operations, authentication)
- DataFrame integration for pandas, polars, and PyArrow
Documentation: https://docs.basekick.net/arc/sdks/python
Azure Blob Storage Backend
Arc now supports Azure Blob Storage as a storage backend, enabling deployment on Microsoft Azure infrastructure.
Configuration options:
storage_backend = "azure"or"azblob"- Connection string authentication
- Account key authentication
- SAS token authentication
- Managed Identity support (recommended for Azure deployments)
Example configuration:
[storage]
backend = "azure"
azure_container = "arc-data"
azure_account_name = "mystorageaccount"
# Use one of: connection_string, account_key, sas_token, or managed identity
azure_use_managed_identity = trueNative TLS/SSL Support
Arc now supports native HTTPS/TLS without requiring a reverse proxy, ideal for users running Arc from native packages (deb/rpm) on bare metal or VMs.
Configuration options:
server.tls_enabled- Enable/disable native TLSserver.tls_cert_file- Path to certificate PEM fileserver.tls_key_file- Path to private key PEM file
Environment variables:
ARC_SERVER_TLS_ENABLEDARC_SERVER_TLS_CERT_FILEARC_SERVER_TLS_KEY_FILE
Example configuration:
[server]
port = 443
tls_enabled = true
tls_cert_file = "/etc/letsencrypt/live/example.com/fullchain.pem"
tls_key_file = "/etc/letsencrypt/live/example.com/privkey.pem"Key features:
- Uses Fiber's built-in
ListenTLS()for direct HTTPS support - Automatic HSTS header (
Strict-Transport-Security) when TLS is enabled - Certificate and key file validation on startup
- Backward compatible - TLS disabled by default
Configurable Ingestion Concurrency
Ingestion concurrency settings are now configurable to support high-concurrency deployments with many simultaneous clients
Configuration options:
ingest.flush_workers- Async flush worker pool size (default: 2x CPU cores, min 8, max 64)ingest.flush_queue_size- Pending flush queue capacity (default: 4x workers, min 100)ingest.shard_count- Buffer shards for lock distribution (default: 32)
Environment variables:
ARC_INGEST_FLUSH_WORKERSARC_INGEST_FLUSH_QUEUE_SIZEARC_INGEST_SHARD_COUNT
Example configuration for high concurrency:
[ingest]
flush_workers = 32 # More workers for parallel I/O
flush_queue_size = 200 # Larger queue for burst handling
shard_count = 64 # More shards to reduce lock contentionKey features:
- Defaults scale dynamically with CPU cores (similar to QuestDB and InfluxDB)
- Previously hardcoded values now tunable for specific workloads
- Helps prevent flush queue overflow under high concurrent load
Data-Time Partitioning
Parquet files are now organized by the data's timestamp instead of ingestion time, enabling proper backfill of historical data.
Key features:
- Historical data lands in correct time-based partitions (e.g., December 2024 data goes to
2024/12/folders, not today's folder) - Batches spanning multiple hours are automatically split into separate files per hour
- Data is sorted by timestamp within each Parquet file for optimal query performance
- Enables accurate partition pruning for time-range queries
How it works:
- Single-hour batches: sorted and written to one file
- Multi-hour batches: split by hour boundary, each hour sorted independently
Example: Backfilling data from December 1st, 2024:
# Before: All data went to ingestion date
data/mydb/cpu/2025/01/04/... (wrong - today's partition)
# After: Data goes to correct historical partition
data/mydb/cpu/2024/12/01/14/... (correct - data's timestamp)
data/mydb/cpu/2024/12/01/15/...
Contributed by @schotime
Compaction API Triggers
Hourly and daily compaction now have separate schedules and can be triggered manually via API.
API Endpoints:
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/v1/compaction/hourly |
Trigger hourly compaction |
POST |
/api/v1/compaction/daily |
Trigger daily compaction |
Configuration:
[compaction]
hourly_schedule = "0 * * * *" # Every hour
daily_schedule = "0 2 * * *" # Daily at 2 AMContributed by @schotime
Configurable Max Payload Size
The maximum request payload size for write endpoints is now configurable, with the default increased from 100MB to 1GB.
Configuration options:
server.max_payload_size- Maximum payload size (e.g., "1GB", "500MB")- Environment variable:
ARC_SERVER_MAX_PAYLOAD_SIZE
Example configuration:
[server]
max_payload_size = "2GB"Key features:
- Applies to both compressed and decompressed payloads
- Supports human-readable units: B, KB, MB, GB
- Improved error messages suggest batching when limit is exceeded
- Default increased 10x from 100MB to 1GB to support larger bulk imports
Database Management API
New REST API endpoints for managing databases programmatically, enabling pre-creation of databases before agents send data.
Endpoints:
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/databases |
List all databases with measurement counts |
POST |
/api/v1/databases |
Create a new database |
GET |
/api/v1/databases/:name |
Get database info |
GET |
/api/v1/databases/:name/measurements |
List measurements in a database |
DELETE |
/api/v1/databases/:name |
Delete a database (requires delete.enabled=true) |
Example usage:
# List databases
curl -H "Authorization: Bearer $TOKEN" http://localhost:8000/api/v1/databases
# Create a database
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "production"}' \
http://localhost:8000/api/v1/databases
# Delete a database (requires confirmation)
curl -X DELETE -H "Authorization: Bearer $TOKEN" \
"http://localhost:8000/api/v1/databases/old_data?confirm=true"Key features:
- Database name validation (alphanumeric, underscore, hyphen; must start with letter; max 64 characters)
- Reserved names protected (
system,internal,_internal) - DELETE respects
delete.enabledconfiguration for safety - DELETE requires
?confirm=truequery parameter - Works with all storage backends (local, S3, Azure)
DuckDB S3 Query Support (httpfs)
Arc now configures the DuckDB httpfs extension automatically, enabling direct queries against Parquet files stored in S3.
Key improvements:
- Automatic httpfs extension installation and configuration
- S3 credentials passed to DuckDB for authenticated access
SET GLOBALused to persist credentials across connection pool- Works with standard S3 buckets (note: S3 Express One Zone uses different auth and is not supported by httpfs)
Configuration:
[storage]
backend = "s3"
s3_bucket = "my-bucket"
s3_region = "us-east-2"
# Credentials via environment variables recommended:
# AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEYImprovements
Storage Backend Interface Enhancements
- Added
ListDirectories()method for efficient partition discovery - Added
ListObjects()method for listing files within partitions - Both local and S3 backends implement the enhanced interface
Compaction Subprocess Improvements
- Fixed "argument list too long" error when compacting partitions with many files
- Job configuration now passed via stdin instead of command-line arguments
- Supports compaction of partitions with 15,000+ files
Arrow Writer Enhancements
- Added row-to-columnar conversion for efficient data ingestion
- Improved buffer management for high-throughput scenarios
Ingestion Pipeline Optimizations
- Zstd compression support: Added Zstd decompression for MessagePack payloads. Zstd achieves 9.57M rec/sec with only 5% overhead vs uncompressed (compared to 12% overhead with GZIP at 8.85M rec/sec). Auto-detected via magic bytes - no client configuration required.
- Consolidated type conversion helpers: Extracted common
toInt64(),toFloat64(),firstNonNil()functions, eliminating ~100 lines of duplicate code across the ingestion pipeline. - O(n log n) column sorting: Replaced O(n²) bubble sort with
sort.Slice()for column ordering in schema inference. - Single-pass timestamp normalization: Reduced from 2-3 passes to single pass for timestamp type conversion and unit normalization.
- Result: 7% throughput improvement (9.47M → 10.1M rec/s), 63% p50 latency reduction (8.40ms → 3.09ms), 84% p99 latency reduction (42.29ms → 6.73ms).
Authentication Performance Optimizations
- Token lookup index: Added
token_prefixcolumn with database index for O(1) token lookup instead of O(n) full table scan. Reduces bcrypt comparisons from O(n/2) average to O(1-2) per cache miss. - Atomic cache counters: Replaced mutex-protected counters with
atomic.Int64operations...
Arc 25.12.1
Arc v25.12.1 - Go Implementation
Major Release: Complete rewrite from Python to Go
Arc is a high-performance time-series database built on DuckDB, optimized for IoT, observability, and analytics workloads.
Migration Highlights
This release marks the complete migration from Python to Go, delivering:
Performance Improvements
- 9.47M records/sec MessagePack ingestion (125% faster than Python's 4.21M)
- 1.92M records/sec Line Protocol ingestion (76% faster than Python's 1.09M)
- 2.88M rows/sec Arrow query throughput
Reliability
- Memory stable: No memory leaks (Python leaked 372MB per 500 queries)
- Single binary: No Python dependencies, pip, or virtual environments
- Type-safe: Strong typing catches bugs at compile time
Full Feature Parity
- ✅ Authentication (user/password)
- ✅ Automatic Compaction (Parquet optimization)
- ✅ Write-Ahead Log (WAL for durability)
- ✅ Retention Policies (automatic data expiration)
- ✅ Continuous Queries (real-time aggregations)
- ✅ Delete API (selective data removal)
- ✅ S3/MinIO storage backend
- ✅ Arrow IPC query responses
Quick Start
Docker
docker run -d \
-p 8000:8000 \
-v arc-data:/app/data \
ghcr.io/basekick-labs/arc:25.12.1Debian/Ubuntu (amd64, arm64)
# Download and install
wget https://github.com/basekick-labs/arc/releases/download/v25.12.1/arc_25.12.1_amd64.deb
sudo dpkg -i arc_25.12.1_amd64.deb
# Start and enable
sudo systemctl enable arc
sudo systemctl start arc
# Check status
curl http://localhost:8000/healthRHEL/Fedora/Rocky (x86_64, aarch64)
# Download and install
wget https://github.com/basekick-labs/arc/releases/download/v25.12.1/arc-25.12.1-1.x86_64.rpm
sudo rpm -i arc-25.12.1-1.x86_64.rpm
# Start and enable
sudo systemctl enable arc
sudo systemctl start arcKubernetes (Helm)
helm install arc https://github.com/basekick-labs/arc/releases/download/v25.12.1/arc-25.12.1.tgzDownload Artifacts
| Platform | Architecture | Package |
|---|---|---|
| Docker | amd64, arm64 | ghcr.io/basekick-labs/arc:25.12.1 |
| Debian/Ubuntu | amd64 | arc_25.12.1_amd64.deb |
| Debian/Ubuntu | arm64 | arc_25.12.1_arm64.deb |
| RHEL/Fedora | x86_64 | arc-25.12.1-1.x86_64.rpm |
| RHEL/Fedora | aarch64 | arc-25.12.1-1.aarch64.rpm |
| Kubernetes | - | arc-25.12.1.tgz (Helm) |
Breaking Changes
- Python version: The Python implementation is preserved in the
python-legacybranch - Configuration: TOML config format (unchanged, but verify your
arc.toml)
Upgrading from Python
- Stop existing Arc service
- Backup your data directory
- Install the new Go binary (same config format)
- Start Arc - data is automatically migrated