Deployment guide

Arc Time-Series Database

Overview

Arc is an open source time series and analytical database from Basekick Labs, distributed under the AGPL 3.0 license. It pairs a high-throughput ingestion pipeline with the DuckDB analytical query engine and stores every record as open Apache Parquet files on your own storage, so any Parquet tool can read your data.

This guide covers the deployment and operation of Arc Time-Series Database on Ubuntu 24.04 on Azure, using SecureAnyCloud Azure Marketplace images.

Arc runs as one statically linked binary. Ingestion, storage, background compaction, SQL query and backup all live in a single process. There is no JVM, no Python environment, no separate metadata service and no cluster to operate. This image installs Arc from the official Basekick Labs package, pinned to 26.09.1 and checksum verified, and runs it under systemd as the unprivileged arc system user.

Arc is a headless database with no web interface. You operate it over its HTTPS API with curl, the Python SDK, a Grafana data source, or any InfluxDB line protocol client such as Telegraf.

Secure by default: token authentication and no default credentials. Arc's own token authentication is enabled, so every query, write and administrative route requires a bearer token. Only four endpoints answer without one: the /health and /ready liveness probes and the /metrics and /api/v1/metrics monitoring endpoints. All four carry aggregate operational counters only. None of them exposes a query, a database or measurement name, a file path or a credential.

On the first boot of every virtual machine, the image generates a unique 48-character admin API token and a unique TLS certificate. It records the token in /root/arc-tsdb-credentials.txt (mode 0600, root only) and only then allows the database to start. A request with no token or a wrong token is rejected with HTTP 401, and no two instances share a secret.

Arc terminates TLS itself on port 8000, so bearer tokens never cross the network in clear text. Port 8000 is upstream's default and is deliberately kept, so the Grafana data source, the Telegraf output plugin and the Python SDK all work without reconfiguration.

What you get:

Arc 26.09.1 from the official Basekick Labs package, run under systemd as the unprivileged arc user (arc.service)

An HTTPS API on port 8000 with a self-signed certificate generated per virtual machine on first boot

Time series data stored as Apache Parquet on a dedicated 30 GB data disk mounted at /var/lib/arc/data

A unique admin API token generated on first boot and recorded in /root/arc-tsdb-credentials.txt (0600), with token authentication enforced on every data route

Automatic background compaction, which merges small Parquet files so scans stay fast and storage stays small

Ingestion over the InfluxDB line protocol, MessagePack columnar and MQTT, and analytical SQL with window functions, common table expressions and joins

Usage telemetry disabled, so the appliance never reports to a third party

Prerequisites

You need an active Azure subscription, an SSH public key, and a VNet and subnet in your target region.

Use a network security group that allows inbound TCP 22 for SSH management and TCP 8000 for the Arc HTTPS API, restricted to the source ranges you trust.

The recommended size is Standard_B2ms (2 vCPU, 8 GiB). Arc's DuckDB memory limit is preconfigured to 3 GB for this size. Raise it if you deploy on a larger VM.

1

Deploy from the Azure Portal

Create the virtual machine from the SecureAnyCloud Arc Time-Series Database on Ubuntu 24.04 image. Choose your resource group, region, size and SSH public key. The 30 GB data disk that carries the Parquet store is defined in the image and is provisioned automatically with the VM, so you do not need to add one.

Once the VM is running, connect over SSH with the admin user that you chose at deployment. On first boot, Arc's first-boot service generates this instance's admin API token and TLS certificate before it allows the database to start. This normally completes within a few seconds of the VM reaching the running state.

2

Retrieve your per-VM admin API token

Every instance generates its own token. Read it from the root-only credentials file:

sudo cat /root/arc-tsdb-credentials.txt

The file records ARC_ADMIN_TOKEN, the ARC_URL endpoint for this VM and the default database name, along with example curl commands. It is mode 0600 and owned by root, so only a user who can already become root on the VM can read it. Keep it secret, and treat the token as a full administrative credential.

3

Verify the service is running

systemctl status arc --no-pager dpkg-query -W -f='arc ${Version}\n' arc ss -ltn | grep 8000 curl -sk https://127.0.0.1:8000/health

arc.service should report active (running), the installed version should be 26.09.1, and Arc should be listening on port 8000 on all interfaces. The /health endpoint is a public liveness probe. It answers without a token and returns a JSON status document.

4

Run your first query

Arc speaks standard analytical SQL over its HTTPS API. Read the token straight from the credentials file so that you never paste a secret onto the command line:

TOKEN=$(sudo grep '^ARC_ADMIN_TOKEN=' /root/arc-tsdb-credentials.txt | cut -d= -f2-)
curl -sk -X POST https://127.0.0.1:8000/api/v1/query \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"sql":"SELECT 1 AS ok"}'

The response is a JSON document with "success":true, a columns array, a data array of rows and a row_count. Because the query engine is DuckDB, the full analytical SQL surface is available, including common table expressions and window functions:

TOKEN=$(sudo grep '^ARC_ADMIN_TOKEN=' /root/arc-tsdb-credentials.txt | cut -d= -f2-)
curl -sk -X POST https://127.0.0.1:8000/api/v1/query \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"sql":"WITH t AS (SELECT 1 AS v UNION ALL SELECT 2 UNION ALL SELECT 3) SELECT v, sum(v) OVER () AS total FROM t ORDER BY v"}'
5

Write and read back time series data

Arc accepts the InfluxDB line protocol, so anything that already writes to InfluxDB 1.x, including Telegraf, can point at Arc unchanged. Write a few points, force a flush so that Arc commits them to Parquet immediately, and then query them back:

TOKEN=$(sudo grep '^ARC_ADMIN_TOKEN=' /root/arc-tsdb-credentials.txt | cut -d= -f2-)
NOW=$(date +%s)000000000 curl -sk -o /dev/null -w 'write: HTTP %{http_code}\n' \
  -X POST 'https://127.0.0.1:8000/write?db=sac' \
  -H "Authorization: Bearer $TOKEN" \
  --data-binary "cpu,host=server01 usage=64.2 $NOW" curl -sk -o /dev/null -X POST https://127.0.0.1:8000/api/v1/write/line-protocol/flush \
  -H "Authorization: Bearer $TOKEN" sleep 2 curl -sk -X POST https://127.0.0.1:8000/api/v1/query \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"sql":"SELECT count(*) AS points FROM sac.cpu"}'

A successful write returns HTTP 204. The read-back query returns "success":true with the number of points stored. In normal operation, you do not need to flush by hand. Arc flushes its ingest buffer automatically, and the explicit flush here only makes the round trip immediate for this walkthrough.

Measurements become tables inside the database that you wrote to, so a point written to measurement cpu in database SecureAnyCloud is queried as sac.cpu. List what a database currently holds with the measurements endpoint:

TOKEN=$(sudo grep '^ARC_ADMIN_TOKEN=' /root/arc-tsdb-credentials.txt | cut -d= -f2-)
curl -sk -H "Authorization: Bearer $TOKEN" https://127.0.0.1:8000/api/v1/measurements
6

Authentication is enforced

Every data route requires the bearer token. The only endpoints that answer without one are the two liveness probes (/health, /ready) and the two monitoring endpoints (/metrics, /api/v1/metrics). The monitoring endpoints expose aggregate counters and no data. Confirm all four cases:

TOKEN=$(sudo grep '^ARC_ADMIN_TOKEN=' /root/arc-tsdb-credentials.txt | cut -d= -f2-)
echo "public /health : HTTP $(curl -sk -o /dev/null -w '%{http_code}' https://127.0.0.1:8000/health)"
echo "no token /query : HTTP $(curl -sk -o /dev/null -w '%{http_code}' -X POST https://127.0.0.1:8000/api/v1/query -H 'Content-Type: application/json' -d '{"sql":"SELECT 1"}')"
echo "bad token /query : HTTP $(curl -sk -o /dev/null -w '%{http_code}' -X POST https://127.0.0.1:8000/api/v1/query -H 'Authorization: Bearer not-a-real-token' -H 'Content-Type: application/json' -d '{"sql":"SELECT 1"}')"
echo "good token /query : HTTP $(curl -sk -o /dev/null -w '%{http_code}' -X POST https://127.0.0.1:8000/api/v1/query -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' -d '{"sql":"SELECT 1"}')" curl -sk -X POST https://127.0.0.1:8000/api/v1/query -H 'Content-Type: application/json' -d '{"sql":"SELECT 1"}'

The public health probe returns 200. The query with no token and the query with a wrong token both return 401 with an "Authentication required" error body and no data. Only the request that carries this VM's token returns 200. The same applies to the write and measurements routes.

You can confirm the rest of the public surface the same way. The two monitoring endpoints answer without a token, while the application log route and the Go profiling endpoints require one:

echo "public /metrics : HTTP $(curl -sk -o /dev/null -w '%{http_code}' https://127.0.0.1:8000/metrics)"
echo "public /api/v1/metrics : HTTP $(curl -sk -o /dev/null -w '%{http_code}' https://127.0.0.1:8000/api/v1/metrics)"
echo "gated /api/v1/logs : HTTP $(curl -sk -o /dev/null -w '%{http_code}' https://127.0.0.1:8000/api/v1/logs)"
echo "gated /debug/pprof/ : HTTP $(curl -sk -o /dev/null -w '%{http_code}' https://127.0.0.1:8000/debug/pprof/)"

The two monitoring endpoints return 200 and are safe to point Prometheus at. /api/v1/logs and the profiling endpoints return 401. If you do not want the monitoring endpoints reachable from outside the VM, restrict port 8000 in your network security group to the addresses that need it.

7

Security posture and where your data lives

sudo stat -c '%a %U:%G %n' /root/arc-tsdb-credentials.txt /etc/arc/arc.toml /etc/arc/tls/arc.key df -h /var/lib/arc/data | tail -1 findmnt -no SOURCE,FSTYPE,SIZE /var/lib/arc/data
sudo find /var/lib/arc/data -name '*.parquet' | head -3 getent passwd arc
sudo grep -E '^(tls_enabled|enabled|local_path|db_path)' /etc/arc/arc.toml

The credentials file is 0600 root:root, the Parquet store is on the dedicated data disk rather than the OS disk,Arc runs as a non-login system user, and the configuration shows TLS enabled and telemetry disabled. Arc writes your time series data as ordinary Parquet files under /var/lib/arc/data, organized by database, measurement and time. You can read the files directly with DuckDB, pandas, polars or any other Parquet reader.

Connecting from a remote client

From any machine that can reach the VM on port 8000, use the public address recorded as ARC_URL in the credentials file. The certificate is self-signed per VM, so pass -k to curl (or the equivalent "skip verification" option in your client) until you install a certificate that your clients already trust:

curl -k -X POST https://<your-vm-ip>:8000/api/v1/query \
  -H "Authorization: Bearer <ARC_ADMIN_TOKEN>" \
  -H 'Content-Type: application/json' \
  -d '{"sql":"SELECT 1 AS ok"}'

To point Telegraf at the appliance, add an outputs.influxdb section whose urls is https://<your-vm-ip>:8000. Set insecure_skip_verify = true while the certificate is self-signed, and supply the token as the HTTP Authorization header. Any existing InfluxDB 1.x writer works the same way.

The Python SDK is published as arc-tsdb-client on PyPI. Basekick Labs also publishes a Grafana data source plugin, a VS Code extension and Apache Superset dialects. All of them expect the port 8000 endpoint that this image keeps.

Using your own TLS certificate

The per-VM certificate is at /etc/arc/tls/arc.crt and its key is at /etc/arc/tls/arc.key. The certificate carries this VM's address in the subject alternative names.

To use your own certificate, replace those two files with a certificate issued for a hostname you control. Alternatively, point tls_cert_file and tls_key_file in /etc/arc/arc.toml at your own paths. Then restart the service with sudo systemctl restart arc. Keep the key readable by the arc group and no wider.

Rotating the admin token

Arc seeds the admin token from ARC_AUTH_BOOTSTRAP_TOKEN in /etc/arc/arc.env on the first start. To rotate it, edit that file with a new value, delete the credential database with sudo rm /var/lib/arc/arc.db, and restart Arc with sudo systemctl restart arc.

Your time series data in /var/lib/arc/data is untouched, because credentials and data are deliberately kept on separate volumes. Record the new value in /root/arc-tsdb-credentials.txt so that the file stays the single source of truth for the instance.

Storage backends

The image stores data locally on the dedicated data disk, which is the right default for a single VM. Arc can also write directly to Azure Blob Storage, Amazon S3 or MinIO. Set backend in the [storage] section of /etc/arc/arc.toml, supply the matching account or bucket settings, and restart the service. Object storage lets the Parquet store grow far beyond the data disk while keeping the same query interface.

Sizing and tuning

The DuckDB query engine is limited to 3 GB of memory with 2 threads, matching the recommended Standard_B2ms. On a larger VM, raise memory_limit and thread_count in the [database] section of /etc/arc/arc.toml and restart Arc.

The ingest buffer is set to 50000 records with a one second maximum age, which suits steady metric collection. For very high write rates, raise max_buffer_size in the [ingest] section. Remember that the buffer is held in memory.

What this image includes

This appliance ships the AGPL 3.0 open source build of Arc with no license key. The full license text is at /opt/arc/LICENSE. Ingestion, storage, compaction, analytical SQL, token authentication, backup and restore, and Prometheus-format metrics are all part of that build.

Basekick Labs separately offers a commercial Enterprise tier that adds clustering, role-based access control, scheduled retention and continuous queries, tiered storage and audit logging. Those features are not part of this image. Because no license key is configured, the appliance never contacts an external license server and runs fully air-gapped.

Managing the service

systemctl is-enabled arc
systemctl is-active arc
sudo journalctl -u arc --no-pager -n 15

Run sudo systemctl restart arc after any configuration change. Run sudo systemctl stop arc before you take a file-level backup of /var/lib/arc.

Troubleshooting

Arc is not running after the first boot. The database deliberately refuses to start until the first-boot service has generated this VM's token. Check that unit first with sudo systemctl status arc-tsdb-firstboot, and read /var/log/sac/sac-firstboot.log. Once the service has completed, /root/arc-tsdb-credentials.txt contains a real token and /var/lib/sac/data/arc-bootstrap-ready exists.

Every request returns 401. Confirm that you send the token from this VM's credentials file as an Authorization: Bearer header. Tokens are per instance and are not interchangeable between VMs.

The connection is refused from a remote machine. Check that the network security group allows inbound TCP 8000 from your source range. Remember that the endpoint is HTTPS, not HTTP.

A certificate warning appears. This is expected while the per-VM certificate is self-signed. Use -k with curl, or install your own certificate as described above.

A query cannot find a table you just wrote. Query points as <database>.<measurement>. Very recent writes may still be in the ingest buffer, so flush explicitly with the line protocol flush endpoint, or wait for the automatic flush.

Support

SecureAnyCloud images include 24/7 support. Raise an issue through the SecureAnyCloud support channel listed on your Azure Marketplace offer, and quote the image name and, where relevant, the output of dpkg-query -W arc. Arc has no --version flag, because running the binary with no subcommand starts the database. Use the package query to report the installed version.

Deploy on Azure

Launch Arc Time-Series Database 26.09.1 on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure