Skip to content

questdb/java-questdb-client

QuestDB Logo

 

Maven Central License

QuestDB Client Library for Java

This is the official Java client library for QuestDB, a high-performance time-series database.

The client uses the InfluxDB Line Protocol (ILP) to insert data into QuestDB over HTTP, TCP, or UDP.

Transport Description
HTTP Recommended. Provides feedback on errors and supports authentication and TLS.
TCP Legacy. No error feedback from server. Useful for compatibility.
UDP Fire-and-forget. No error feedback or delivery guarantees. Supports multicast.

Quick Start

Add Dependency

Maven:

<dependency>
    <groupId>org.questdb</groupId>
    <artifactId>client</artifactId>
    <version>1.0.0</version>
</dependency>

Gradle:

implementation 'org.questdb:client:1.0.0'

Replace 1.0.0 with the latest version from Maven Central.

Start QuestDB

docker run -p 9000:9000 questdb/questdb

Insert Data

import io.questdb.client.Sender;

public class Main {
    public static void main(String[] args) {
        try (Sender sender = Sender.fromConfig("http::addr=localhost:9000;")) {
            sender.table("trades")
                    .symbol("symbol", "ETH-USD")
                    .symbol("side", "sell")
                    .doubleColumn("price", 2615.54)
                    .doubleColumn("amount", 0.00044)
                    .atNow();
        }
    }
}

More Examples

Using the Builder API

import io.questdb.client.Sender;

try (Sender sender = Sender.builder(Sender.Transport.HTTP)
        .address("localhost:9000")
        .autoFlushRows(1000)
        .autoFlushIntervalMillis(5000)
        .build()) {
    sender.table("trades")
            .symbol("symbol", "ETH-USD")
            .doubleColumn("price", 2615.54)
            .atNow();
}

TCP Transport

try (Sender sender = Sender.fromConfig("tcp::addr=localhost:9009;")) {
    sender.table("trades")
            .symbol("symbol", "ETH-USD")
            .symbol("side", "sell")
            .doubleColumn("price", 2615.54)
            .doubleColumn("amount", 0.00044)
            .atNow();
}

UDP Transport

UDP uses LineUdpSender directly (not available via Sender.fromConfig()). It is fire-and-forget with no delivery guarantees.

import io.questdb.client.cutlass.line.LineUdpSender;
import io.questdb.client.std.Numbers;
import io.questdb.client.std.NumericException;

// Parameters: interface IPv4 address, target IPv4 address, target port, buffer capacity, TTL
int lo = Numbers.parseIPv4("127.0.0.1");
int target = Numbers.parseIPv4("127.0.0.1");
try (LineUdpSender sender = new LineUdpSender(lo, target, 9009, 1024, 2)) {
    sender.table("trades")
            .symbol("symbol", "ETH-USD")
            .doubleColumn("price", 2615.54)
            .atNow();
    sender.flush();
}

Authentication and TLS

HTTP with username/password:

try (Sender sender = Sender.fromConfig("https::addr=localhost:9000;username=admin;password=quest;")) {
    // ...
}

HTTP with bearer token:

try (Sender sender = Sender.fromConfig("http::addr=localhost:9000;token=my_bearer_token;")) {
    // ...
}

TCP with authentication:

try (Sender sender = Sender.fromConfig("tcp::addr=localhost:9009;user=admin;token=my_token;")) {
    // ...
}

TLS with certificate validation disabled (not for production):

try (Sender sender = Sender.fromConfig("https::addr=localhost:9000;tls_verify=unsafe_off;")) {
    // ...
}

Explicit Timestamps

import java.time.Instant;
import java.time.temporal.ChronoUnit;

try (Sender sender = Sender.fromConfig("http::addr=localhost:9000;")) {
    // Using an Instant
    sender.table("trades")
            .symbol("symbol", "ETH-USD")
            .doubleColumn("price", 2615.54)
            .at(Instant.now());

    // Using a long value with time unit
    sender.table("trades")
            .symbol("symbol", "BTC-USD")
            .doubleColumn("price", 39269.98)
            .at(1_000_000_000L, ChronoUnit.NANOS);
}

Configuration via Environment Variable

Instead of hardcoding the configuration string, set the QDB_CLIENT_CONF environment variable:

export QDB_CLIENT_CONF="http::addr=localhost:9000;"

Then create the sender:

try (Sender sender = Sender.fromEnv()) {
    // ...
}

Configuration Reference

The configuration string format is:

schema::key1=value1;key2=value2;

Schemas: http, https, tcp, tcps

Key Default Description
addr (required) Server address as host:port
username HTTP basic auth username
password HTTP basic auth password
token Bearer token (HTTP) or private key token (TCP)
user Username for TCP auth
tls_verify on TLS certificate validation (on or unsafe_off)
tls_roots Path to custom truststore
tls_roots_password Truststore password
auto_flush on Enable auto-flush (on or off)
auto_flush_rows 75000 Flush after N rows (HTTP only)
auto_flush_interval 1000 Flush interval in milliseconds (HTTP; off to disable)
request_timeout 30000 HTTP request timeout in milliseconds
request_min_throughput 102400 Min expected throughput in bytes/sec (HTTP)
retry_timeout 10000 Total retry duration in milliseconds (HTTP)
max_buf_size 104857600 Maximum buffer capacity in bytes
max_name_len 127 Maximum table/column name length
protocol_version auto ILP protocol version (1, 2, 3, or auto)

For the full configuration reference, see the QuestDB ILP documentation.

Requirements

  • Java 11 or later
  • Maven 3+ (for building from source)

Building from Source

git clone https://github.com/questdb/java-questdb-client.git
cd java-questdb-client
mvn clean package -DskipTests

Building Native Libraries

The client includes native libraries (C/C++ and assembly) for performance-critical operations. Pre-built binaries are included in the repository, but you can rebuild them locally if needed.

Prerequisites

Tool Version Notes
CMake 3.5+ Build system generator
NASM 2.14+ Netwide Assembler for assembly code
C/C++ Compiler GCC, Clang, or MinGW C++17 support required
Make Any Build tool
JDK 11+ For JNI headers

macOS (ARM64 or x86-64)

# Install build tools
brew install cmake nasm

# Set deployment target
export MACOSX_DEPLOYMENT_TARGET=13.0

# Build native library
cd core
cmake -B cmake-build-release -DCMAKE_BUILD_TYPE=Release
cmake --build cmake-build-release --config Release

Linux x86-64

# Install build tools (Debian/Ubuntu)
sudo apt-get install cmake nasm build-essential

# Build native library
cd core
cmake -DCMAKE_BUILD_TYPE=Release -B cmake-build-release -S.
cmake --build cmake-build-release --config Release

Linux ARM64

# Install build tools (Debian/Ubuntu)
sudo apt-get install cmake nasm build-essential

# Build using ARM64 toolchain
cd core
cmake -DCMAKE_TOOLCHAIN_FILE=./src/main/c/toolchains/linux-arm64.cmake \
      -DCMAKE_BUILD_TYPE=Release -B cmake-build-release-arm64 -S.
cmake --build cmake-build-release-arm64 --config Release

Windows x86-64 (Cross-compilation from Linux)

# Install cross-compilation tools (Debian/Ubuntu)
sudo apt-get install cmake nasm gcc-mingw-w64 g++-mingw-w64

# Build using Windows toolchain
cd core
cmake -DCMAKE_TOOLCHAIN_FILE=./src/main/c/toolchains/windows-x86_64.cmake \
      -DCMAKE_CROSSCOMPILING=True -DCMAKE_BUILD_TYPE=Release \
      -B cmake-build-release-win64
cmake --build cmake-build-release-win64 --config Release

Native Library Output Locations

Built libraries are placed in the resources directory for each platform:

core/target/classes/io/questdb/client/bin-local/
├── libquestdb.dylib  # macOS
├── libquestdb.so     # Linux
└── libquestdb.dll    # Windows

Community

License

This project is licensed under the Apache License 2.0.

About

Java client for QuestDB InfluxDB Line Protocol

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •