Skip to content

KDB+ Documentation

Welcome to KDB+ (Q) documentation covering setup, operations, and integration examples for this high-performance time-series database.

Overview

KDB+ is a high-performance column-oriented database with a built-in expressive query and programming language called Q. It's particularly well-suited for financial time-series data and real-time analytics.

Getting Started

Prerequisites

  • KDB+ installation (see setup guide)
  • Basic understanding of columnar databases
  • Familiarity with functional programming concepts

Quick Start

  1. Setup KDB+ on M3 - Installation guide for ARM-based Macs
  2. Connect manually - Basic connection methods
  3. Simple Demo - Working examples and tutorials

Core Concepts

Essential Commands

1
2
3
4
5
// List all tables in root namespace
q)tables `.

// Check dictionary structure
q).u.w  // tick subscription dictionary

Table Operations

Creating Tables

1
2
3
4
5
6
7
8
9
// Define stock table schema
stocks:([] time:`timestamp$(); sym:`symbol$(); price:`float$())

// Insert single record
`stocks insert (.z.p; `AAPL; 170.11)

// Upsert with structured data
row: flip `time`sym`price! (enlist .z.p; enlist `AAPL; enlist 189.3)
stocks upsert row

Integration Patterns

Java Integration

For Java applications connecting to KDB+:

Reading Data

private static void printStocks(c c) throws c.KException, IOException {
    // KDB+ query: select from stocks where time < .z.p, sorted by time descending
    String query = "xdesc[`time] select from stocks where time < .z.p";

    // Send query and receive result
    Object result_kdb = c.k(query);

    Flip table = (Flip) result_kdb;
    String[] columnNames = table.x;
    Object[] columnData = table.y;

    int rowCount = Array.getLength(columnData[0]);

    for (int i = 0; i < rowCount; i++) {
        StringBuilder row = new StringBuilder();
        for (int j = 0; j < columnNames.length; j++) {
            Object col = columnData[j];
            Object value = Array.get(col, i);
            row.append(columnNames[j]).append("=").append(value).append(" ");
        }
        System.out.println(row.toString());
    }
}

Writing Data

1
2
3
4
private static void insertStock(c c, String sym, double price) throws c.KException, IOException {
    String query = String.format("`stocks insert (.z.p; `%s; %f)", sym, price);
    c.ks(query);
}

Real-time Data Streaming

Q Process Setup

# Start Q process with port
q -p 1234
// Define stream schema
stocks:([] time:`timestamp$(); sym:`symbol$(); price:`float$());

// Load tick utilities
\l tick/u.q
.u.init[]

// Memory management - keep only last minute of data
.z.ts:{ `stocks set select from stocks where time > .z.p - 00:01:00.000 };
\t 1000  // Execute every second

Dashboard Integration

For KX Dashboard connections:

  1. Data Source Configuration: Use DataSource->kdb+/q
  2. Query for latest data:
    `time xdesc select from stocks where time < .z.p
    
  3. Subscription Settings:
  4. Polling: Enabled
  5. Force Reset: Enabled
  6. Interval: 1s
  7. Key: Row Num

Advanced Topics

Memory Management

1
2
3
4
5
// Keep only latest 10 records
.z.ts:{ `stocks set select from stocks where i > (count stocks) - 10 }

// Time-based retention (10 minutes)
.z.ts:{ `stocks set delete from stocks where time < .z.p - 00:10:00.000 }

Tick Integration

// Initialize tick publishing
\l tick/u.q
.u.init[]

// Define update function for dashboards
.u.upd:{[table; data] insert[table; flip data]; .u.pub[table; flip data];}
.u.snap:{stocks}

// Publish updates every second
\t 1000
.z.ts:{ .u.pub[`stocks; .u.snap[`stocks]] }

Additional Resources


Performance Considerations

KDB+ excels at time-series operations. Design your schemas and queries with columnar access patterns in mind for optimal performance.