# AtlasKV

AtlasKV is a distributed, strongly consistent key-value store for applications that need predictable reads and writes across multiple nodes. It uses the Raft consensus algorithm to replicate data, elect leaders, and recover from node failures without manual intervention.

AtlasKV is designed for configuration data, service coordination, metadata, feature flags, and other workloads where correctness matters more than complex queries.

## Features

- Strongly consistent reads and writes
- Raft-based replication and leader election
- Automatic recovery from node failures
- Compare-and-swap operations
- Key expiration with configurable TTLs
- Prefix-based key listing and watches
- HTTP and gRPC APIs
- Persistent storage with write-ahead logging
- TLS encryption and optional mutual TLS
- Prometheus-compatible metrics
- Graceful snapshots and log compaction

## Installation

### Prebuilt binaries

Download the archive for your platform from the project releases page, then install the server and CLI:

```sh
tar -xzf atlaskv_1.4.0_linux_amd64.tar.gz
sudo install atlaskv atlaskvctl /usr/local/bin/
```

Verify the installation:

```sh
atlaskv --version
atlaskvctl --version
```

### Docker

```sh
docker pull ghcr.io/atlaskv/atlaskv:1.4.0
```

### Build from source

AtlasKV requires Go 1.23 or later.

```sh
git clone https://github.com/atlaskv/atlaskv.git
cd atlaskv
make build
```

The compiled binaries are written to `bin/`.

## Usage

### Start a single-node server

Single-node mode is useful for local development:

```sh
atlaskv server \
  --node-id node-1 \
  --data-dir ./data \
  --client-addr 127.0.0.1:7400 \
  --peer-addr 127.0.0.1:7401 \
  --bootstrap
```

Check the server:

```sh
atlaskvctl --endpoint http://127.0.0.1:7400 status
```

### Store and retrieve values

```sh
atlaskvctl put /services/api/url "https://api.example.com"
atlaskvctl get /services/api/url
```

Delete a key:

```sh
atlaskvctl delete /services/api/url
```

List keys by prefix:

```sh
atlaskvctl list /services/
```

Set a key that expires after five minutes:

```sh
atlaskvctl put /sessions/8f32d1 '{"user_id":42}' --ttl 5m
```

Update a key only if its current revision matches:

```sh
atlaskvctl put /config/version "2" --if-revision 17
```

Watch for changes:

```sh
atlaskvctl watch /config/ --prefix
```

### HTTP API

Write a value:

```sh
curl -X PUT http://127.0.0.1:7400/v1/kv/services/api/url \
  -H 'Content-Type: application/json' \
  -d '{"value":"https://api.example.com"}'
```

Read it:

```sh
curl http://127.0.0.1:7400/v1/kv/services/api/url
```

Delete it:

```sh
curl -X DELETE http://127.0.0.1:7400/v1/kv/services/api/url
```

### Start a three-node cluster

Start the first node and bootstrap the cluster:

```sh
atlaskv server --config ./config/node-1.yaml --bootstrap
```

Start the remaining nodes:

```sh
atlaskv server --config ./config/node-2.yaml
atlaskv server --config ./config/node-3.yaml
```

Each node must have a unique node ID and peer address. Production clusters should use an odd number of nodes, usually three or five, distributed across independent failure domains.

## Configuration

AtlasKV accepts command-line flags, environment variables, or a YAML configuration file. Command-line flags take precedence over environment variables, which take precedence over file settings.

Example `atlaskv.yaml`:

```yaml
node:
  id: node-1
  data_dir: /var/lib/atlaskv
  bootstrap: false

network:
  client_addr: 0.0.0.0:7400
  peer_addr: 0.0.0.0:7401
  advertise_client_addr: atlaskv-1.internal:7400
  advertise_peer_addr: atlaskv-1.internal:7401

cluster:
  peers:
    - id: node-1
      address: atlaskv-1.internal:7401
    - id: node-2
      address: atlaskv-2.internal:7401
    - id: node-3
      address: atlaskv-3.internal:7401

storage:
  sync_writes: true
  snapshot_interval: 10000
  max_wal_size: 512MiB

timeouts:
  election: 2s
  heartbeat: 250ms
  request: 5s

tls:
  enabled: true
  cert_file: /etc/atlaskv/tls/server.crt
  key_file: /etc/atlaskv/tls/server.key
  ca_file: /etc/atlaskv/tls/ca.crt
  require_client_cert: true

observability:
  log_level: info
  log_format: json
  metrics_addr: 0.0.0.0:9090
```

Start the server with the configuration file:

```sh
atlaskv server --config /etc/atlaskv/atlaskv.yaml
```

Common environment variables include:

| Variable | Description | Default |
|---|---|---|
| `ATLASKV_NODE_ID` | Unique node identifier | Required |
| `ATLASKV_DATA_DIR` | Persistent data directory | `./data` |
| `ATLASKV_CLIENT_ADDR` | Client API listen address | `127.0.0.1:7400` |
| `ATLASKV_PEER_ADDR` | Raft peer listen address | `127.0.0.1:7401` |
| `ATLASKV_LOG_LEVEL` | `debug`, `info`, `warn`, or `error` | `info` |
| `ATLASKV_METRICS_ADDR` | Prometheus metrics address | Disabled |
| `ATLASKV_TLS_ENABLED` | Enable TLS for client and peer traffic | `false` |

Run `atlaskv server --help` for the complete configuration reference.