> ## Documentation Index
> Fetch the complete documentation index at: https://docs.textql.com/llms.txt
> Use this file to discover all available pages before exploring further.

# kdb+ Connector

> Connecting TextQL to kdb+ (kx/q)

[kdb+](https://kx.com/) is a high-performance column-oriented database from KX, used heavily for time-series and financial data. It speaks its own binary protocol rather than SQL, and its query language is **q** (with a SQL-like subset, qSQL) — so TextQL sends q/qSQL, not standard SQL.

<Note>
  New to kdb+/q? Helpful references:

  * [Q for Mortals](https://code.kx.com/q4m3/) — the canonical guide to the q language
  * [kdb+ & q documentation](https://code.kx.com/q/) — official reference
  * [qSQL queries](https://code.kx.com/q/basics/qsql/) — the `select … by … from … where` subset
  * [Interprocess communication](https://code.kx.com/q/basics/ipc/) — how clients connect to a q process
</Note>

To connect TextQL with your kdb+ process, you will need:

* The host and port the q process listens on
* Credentials (username/password), if the process requires authentication
* Whether the connection uses TLS

### Creating the Connector in TextQL

Navigate to the [TextQL Connectors Page](/core/datasources/the-connectors-page) and click **Create New Connector**. Select kdb+ from the available connectors to open the configuration form.

The form requires the following information:

* **Connector Name:** A descriptive name to identify this kdb+ connection in TextQL.
* **Host:** The hostname or IP of the q process (e.g., `kdb.internal.example.com`).
* **Port:** The TCP port the q process listens on. kdb+ has no fixed default — it is set per process (commonly `5000` or `5001`).
* **Username / Password:** Credentials, if the process enforces authentication. Leave blank for an unauthenticated process.
* **Use TLS:** Enable if the q process listens with TLS (`hopen` over `tcps://`).

### How TextQL queries kdb+

kdb+ is not a SQL database — it speaks its own binary IPC protocol, and its query language is **q / qSQL**, not ANSI SQL. TextQL connects directly over IPC and sends qSQL. A few differences to keep in mind when writing queries:

* Use qSQL: `select sym, price from trade where size > 1000`.
* There is no `*` wildcard — omit the select phrase to return all columns (`select from trade`).
* `by` performs grouping and aggregation; there is no `order by` (sort with `xasc` / `xdesc`).
* Evaluation order is From → Where → By → Select.

Column types are mapped to their natural equivalents (symbol → text, timestamp → timestamp, long → bigint, float → double, etc.), and q nulls are surfaced as nulls.

### Authentication

A q process authenticates clients with a password file supplied at startup via the `-u` or `-U` flag (one `username:password` per line; the password may be plain or an MD5/SHA-1 hash). Provide the matching username and password in the connector form. For custom auth schemes (LDAP, Kerberos), the process implements a `.z.pw` handler — supply whatever username/password that handler expects.

### Security

<Warning>
  An open kdb+ port with no other measures is **unauthenticated remote code execution** — the default message handler evaluates whatever a client sends. Before exposing a q process to TextQL (or anything else), lock it down.
</Warning>

TextQL only issues read queries, but the server is what actually enforces access — restrict it on the kdb+ side:

* **Authenticate** with a password file (`-u <file>`). Note that lowercase `-u` adds restrictions (blocks remote system commands and out-of-tree file access); uppercase `-U` is authentication only.
* **Sandbox queries** by overriding the message handlers to run under restricted eval, e.g. `.z.pg:{reval(value;x)}` (and the same for `.z.ps`). Under `reval`, reads succeed but writes raise `'noupdate` and system commands raise `'access`.
* **Block writes** with `-b` if the process should never be mutated over IPC.
* Prefer **TLS** for any connection that leaves the host. Keep connections long-lived — the TLS handshake is expensive.

<Note>
  These restrictions began blocking `hopen` of files, `hdel`, and `exit` in kdb+ V4.0 / V4.1 (2021–2023). On older builds, `reval` / `-u 1` are leakier — pin a minimum version if your threat model depends on them.
</Note>

### Resource limits (timeout & memory)

A single broad query against a large HDB can run for minutes or exhaust the process's memory and take the whole q process down. kdb+ does not impose these limits by default — set them on the server so a TextQL query (or any client) can never exhaust it:

* **Cap query time** with the `-T` startup flag (timeout in **seconds**). A client request that exceeds it is aborted with `'stop`, freeing the process. For example, `q hdb.q -T 30` stops any query running longer than 30 seconds. You can also set it live with the `\T` system command (`\T 30`).
* **Cap memory** with the `-w` startup flag (workspace limit in **MB**). When a query would allocate past the cap, q raises `'wsfull` instead of letting the OS OOM-kill the process. For example, `q hdb.q -w 64000` caps the workspace at \~64 GB. Inspect live usage with the `\w` system command or `.Q.w[]` — note these report **in bytes**, not MB.
* **Limit secondary threads** with `-s` if you run multi-threaded queries, so a single client can't saturate every core.

<Note>
  Set `-T` and `-w` to values that comfortably fit your largest *legitimate* query — too low and normal TextQL questions fail with `'stop` or `'wsfull`; too high and a runaway query can still hurt. A timeout in the tens of seconds and a workspace cap below the host's physical RAM are sensible starting points.
</Note>

### Testing the Connection

After entering your details, click **Create**. TextQL validates the credentials, runs a test query (`1+1`), and creates the connector. If the connection fails:

* **Connection refused / timeout** — the host/port is wrong, the q process isn't listening on that port, or a firewall is blocking it.
* **`access`** — the username/password was rejected by the process's password file or `.z.pw` handler.
* **Compressed-response errors against an off-host server** — fully supported; if you hit a decode error, report it with the server's kdb+ version.

<Note>
  Having trouble connecting? See the [Network Configuration Guide](/core/datasources/databases/network-configuration) for firewall and IP whitelisting setup. kdb+ IPC runs over a single TCP port — ensure your firewall allows outbound access to the host and port you configured.
</Note>

### Next Steps

Once connected, you can use TextQL to query your kdb+ tables. For a safe production setup:

* Point TextQL at a **read-only** q process (an RDB/HDB query gateway), not a process that ingests or mutates data
* Sandbox the query handlers with `reval` so the connector can only read
* Use a dedicated credential for TextQL rather than a shared one
