Quickstart
Docker Compose is the fastest way to try Kronotop. Prebuilt jars are also available on the
Releases page(opens in a new tab). Download them and run them with java -jar. This
needs Java 25 or newer. To build Kronotop from source and run a node locally, see the
Building and Running guide(opens in a new tab).
Start the cluster
Section titled “Start the cluster”Download the Docker Compose file:
curl -O https://kronotop.com/kronotop-quickstart.yamlStart the cluster:
docker compose -f kronotop-quickstart.yaml upThis starts a minimal cluster: one FoundationDB instance, one Kronotop primary node, and one standby node. The primary owns bucket shard 0, and the standby replicates it for failover.
Connect
Section titled “Connect”Once all containers are running, connect with kronotop-cli on port 3320:
docker run --rm -it --platform linux/amd64 --network kronotop \ ghcr.io/kronotop/kronotop:latest kronotop-cli -h kronotop-primary -p 3320If you have kronotop-cli or valkey-cli installed locally, you can connect with that instead:
valkey-cli -p 3320Verify the cluster is up:
kronotop-primary:3320> PINGPONGkronotop-primary:3320> KR.ADMIN DESCRIBE-CLUSTER1# "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"Session setup
Section titled “Session setup”Port 3320 is the internal/admin port. Client traffic uses port 5484. Connect to the client port:
docker run --rm -it --platform linux/amd64 --network kronotop \ ghcr.io/kronotop/kronotop:latest kronotop-cli -h kronotop-primary -p 5484If you use valkey-cli, set the session attributes below for human-readable output. kronotop-cli sets them
automatically.
SESSION.ATTRIBUTE SET input_type jsonSESSION.ATTRIBUTE SET reply_type jsonSESSION.ATTRIBUTE SET object_id_format hexInsert and query a document
Section titled “Insert and query a document”Create a bucket:
kronotop-primary:5484> BUCKET.CREATE ordersOKInsert 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) 12# "entries" => 1) {"_id": "6a133c8806bf494c9e7e00cb", "item": "keyboard", "qty": 2, "price": 49.99}One transaction, multiple models
Section titled “One transaction, multiple models”Different data models and namespaces can share one strictly serializable transaction. In the example below, one transaction writes a document in one namespace and updates a counter in another, and both changes commit atomically:
BEGIN
# In the sales namespace: record a new order.NAMESPACE USE production.salesBUCKET.INSERT orders DOCS '{"item": "keyboard", "qty": 2, "price": 49.99}'
# In the inventory namespace: decrement stock, conflict-free.NAMESPACE USE production.inventoryZINC.I64 keyboard -2
COMMITNamespaces must exist before you use them. Create them with NAMESPACE CREATE production.sales and
NAMESPACE CREATE production.inventory.
Next steps
Section titled “Next steps”- Bucket Tutorial: a walkthrough of the Bucket API, from creating a bucket to removing it
- BQL Reference: the query language in full
- ZMap: the ordered key-value model
- Transactions: explicit transactions and snapshot reads
- Namespaces: logical isolation and cross-namespace transactions
- Configuration Reference: overriding the built-in defaults