Skip to content

Quickstart

The fastest way to try Kronotop is with Docker Compose. Prebuilt jars are also published on the Releases page; download them and run with java -jar, which requires Java 25 or newer. If you want to build Kronotop from source and run a node locally, see the Building and Running guide.

Download the Docker Compose file:

Terminal window
curl -O https://kronotop.com/kronotop-quickstart.yaml

Start the cluster:

Terminal window
docker compose -f kronotop-quickstart.yaml up

This starts a minimal cluster: one FoundationDB instance, one Kronotop primary node, and one standby node. The primary owns bucket shard 0; the standby replicates it for failover.

Once all containers are running, connect with kronotop-cli on port 3320:

Terminal window
docker run --rm -it --platform linux/amd64 --network kronotop \
ghcr.io/kronotop/kronotop:latest kronotop-cli -h kronotop-primary -p 3320

Alternatively, you can use kronotop-cli or valkey-cli if you have them installed locally:

Terminal window
valkey-cli -p 3320

Verify the cluster is up:

kronotop-primary:3320> PING
PONG
kronotop-primary:3320> KR.ADMIN DESCRIBE-CLUSTER
1# "metadata_version" => "1.0.0"
2# "cluster_name" => "development"
3# "bucket" =>
1# (integer) 0 =>
1# "primary" => "f627bf46f8627333a064de5c388d0316cc223a54"
2# "standbys" => 1) "e159f73fb21cd6ac80639b2cc1e087e8330cd947"
3# "status" => "READWRITE"
4# "linked_volumes" => 1) "bucket-shard-0"

Port 3320 is the internal/admin port. Client traffic goes through port 5484. Connect to the client port:

Terminal window
docker run --rm -it --platform linux/amd64 --network kronotop \
ghcr.io/kronotop/kronotop:latest kronotop-cli -h kronotop-primary -p 5484

kronotop-cli sets these automatically. If you are using valkey-cli, set the session attributes manually for human-readable output:

SESSION.ATTRIBUTE SET input_type json
SESSION.ATTRIBUTE SET reply_type json
SESSION.ATTRIBUTE SET object_id_format hex

Create a bucket:

kronotop-primary:5484> BUCKET.CREATE orders
OK

Insert a document:

kronotop-primary:5484> BUCKET.INSERT orders DOCS '{
"item": "keyboard",
"qty": 2,
"price": 49.99
}'
1) "6a133c8806bf494c9e7e00cb"

Query it back with the Bucket Query Language (BQL):

kronotop-primary:5484> BUCKET.QUERY orders '{"qty": {"$gte": 1}}'
1# "cursor_id" => (integer) 1
2# "entries" => 1) {"_id": "6a133c8806bf494c9e7e00cb", "item": "keyboard", "qty": 2, "price": 49.99}

Kronotop allows different data models and namespaces to participate in the same strictly serializable transaction boundary. A single transaction can atomically write a document and update a counter across isolated namespaces:

BEGIN
# In the sales namespace: record a new order.
NAMESPACE USE production.sales
BUCKET.INSERT orders DOCS '{"item": "keyboard", "qty": 2, "price": 49.99}'
# In the inventory namespace: decrement stock, conflict-free.
NAMESPACE USE production.inventory
ZINC.I64 keyboard -2
COMMIT

Namespaces must exist before use; create them with NAMESPACE CREATE production.sales and NAMESPACE CREATE production.inventory.