Primer#
This primer shows how to start quasardb, create a time-series table, insert data, run queries, and organize entries with tags.
About quasardb#
quasardb is a distributed, column-oriented database for numerical and time-series data at petabyte scale. It continuously ingests data while it serves real-time queries across live and historical datasets.
quasardb combines ingestion, compressed tiered storage, and distributed query execution in one engine. Use it when you must:
Sustain high ingestion rates while queries continue to run
Store large numerical datasets efficiently across NVMe and object storage
Query live and historical data through one logical database
Reduce the need for separate streaming, historian, warehouse, and data-lake systems
You can access the same data through SQL, client APIs, and standard interfaces. You do not need to duplicate the data between separate processing systems.
Start a local cluster#
The following commands start a quasardb server in Docker. The server listens on port 2836. It also uses port 2837 for cluster communication.
Create a Docker network:
docker network create qdb-network
Start the server:
docker run --detach \
--name qdb-server \
--network qdb-network \
--publish 2836-2837:2836-2837 \
bureau14/qdb
Confirm that the container is running:
docker ps --filter name=qdb-server
For installation options and system requirements, refer to Installation.
Start the shell#
Run the quasardb shell in a second terminal:
docker run --rm --interactive --tty \
--network qdb-network \
bureau14/qdbsh \
--cluster qdb://qdb-server:2836
The shell displays this prompt:
qdbsh >
Enter each SQL statement after the prompt. End a statement with a semicolon. For more information about the shell, refer to quasardb shell.
Create a table#
Create a time-series table named stocks:
CREATE TABLE stocks (
$timestamp TIMESTAMP,
close DOUBLE
);
$timestamp is the time index. The close column stores 64-bit
floating-point values.
Display the table schema:
SHOW TABLE stocks;
Create a table only once. To remove the table and all its data, run:
DROP TABLE stocks;
Do not run this command if you want to continue the tutorial.
Insert data#
Insert three rows:
INSERT INTO stocks ($timestamp, close) VALUES
(2026-01-01, 1.0),
(2026-01-02, 2.0),
(2026-01-03, 3.0);
Each value corresponds to the column at the same position in the column list. For more information, refer to INSERT INTO … VALUES.
Query the data#
Select the rows that you inserted:
SELECT $timestamp, close
FROM stocks
IN RANGE (2026-01-01, 2026-01-04);
The range includes its start and excludes its end. The query returns these values:
|
|
|---|---|
|
|
|
|
|
|
You can use a duration to specify the end of a range:
SELECT $timestamp, close
FROM stocks
IN RANGE (2026-01-01, +3days);
Filter rows with WHERE:
SELECT $timestamp, close
FROM stocks
IN RANGE (2026-01-01, +3days)
WHERE close < 2.0;
Calculate the arithmetic mean on the server. avg() is an alias for
arithmetic_mean():
SELECT avg(close) AS mean_close
FROM stocks
IN RANGE (2026-01-01, +3days);
This query returns one value: 2.0.
Group values into one-day intervals:
SELECT $timestamp, avg(close) AS mean_close
FROM stocks
IN RANGE (2026-01-01, +3days)
GROUP BY 1day;
Use OVER to calculate a three-day moving average of the daily values:
SELECT
$timestamp,
avg(avg(close)) OVER (
RANGE ($timestamp - 2days, $timestamp)
) AS moving_avg_3day
FROM stocks
IN RANGE (2026-01-01, +3days)
GROUP BY 1day;
The inner avg(close) calculates one value for each day. The outer avg
calculates the mean of the current daily value and the values from the two
previous days. The time-based window moves with each result row.
SELECT * also returns the virtual $timestamp and $table columns
for a time-series table. Select explicit columns when you do not need
$table.
For complete query syntax, refer to SELECT and the function reference.
Use the Python API#
The Python API can create tables and write NumPy arrays. The following example
creates a separate table named python_stocks and inserts three rows.
Install the API and NumPy in your Python environment before you run the example.
import numpy as np
import quasardb
timestamps = np.array(
["2026-01-01", "2026-01-02", "2026-01-03"],
dtype="datetime64[ns]",
)
close_values = np.array([1.0, 2.0, 3.0], dtype="float64")
with quasardb.Cluster("qdb://127.0.0.1:2836") as cluster:
table = cluster.table("python_stocks")
if table.exists():
table.remove()
table.create([
quasardb.ColumnInfo(quasardb.ColumnType.Double, "close")
])
data = quasardb.WriterData()
data.append(table, timestamps, [close_values])
writer = cluster.writer()
writer.push(data, push_mode=quasardb.WriterPushMode.Fast)
The example removes python_stocks if it exists. Do not use this pattern for
a production table.
The fast push mode is suitable for large batch loads. For streaming data or frequent small writes, use the asynchronous push mode. For more information, refer to Batch inserter and Python.
Connect to a production cluster#
The client uses the connection URI to contact one or more initial nodes. It then discovers the cluster topology.
Specify multiple initial nodes so that the client can connect when one node is not available:
import datetime
c = quasardb.Cluster("qdb://127.0.0.1:2836,192.168.1.2:2836,192.168.1.3:2836,192.168.1.4:2836", timeout=datetime.timedelta(minutes=1))
Production clusters can require user credentials and a cluster public key. For security configuration, refer to Security.
Stop the local cluster#
When you finish the tutorial, stop and remove the server container:
docker stop qdb-server
docker rm qdb-server
docker network rm qdb-network
Next steps#
Continue with the documentation that applies to your work:
Query language for SQL syntax
APIs for client APIs
Server Administration for cluster administration
Internals for architecture and storage concepts