TorQ Integration Runbook (Sravz)
This document captures the TorQ/KDB work completed in this repo so far, including fixes, runtime commands, SSL work, and websocket feed integration notes.
Environment
- Local compose file:
localhost-docker-compose.yaml - TorQ container name pattern:
sravz-torq-1 - KDB runtime: KDB-X 5.0 (Community)
- TorQ core in container:
/opt/backend-q/deploy/TorQ/latest - TorQ app in container:
/opt/backend-q/deploy/TorQApp/latest
Major Fixes Completed
1) KDB-X .Q.lim[] compatibility bug in TorQ core
Issue:
- TorQ checked connection limit with
0W=.Q.lim[][\conns]`. - In KDB-X CE,
.Q.lim[]returns a dict (cur|...,lim|...) and this comparison failed.
Fix:
- Extract limit scalar from nested dict:
x[\conns][`lim]`.
Files updated:
backend-q/TorQ/config/settings/default.qbackend-q/TorQ/config/settings/segmentedchainedtickerplant.q- Matching app override restored in:
deploy/TorQApp/v1.12.1/TorQ-Finance-Starter-Pack-1.12.1/appconfig/settings/segmentedchainedtickerplant.q
Result:
- Discovery/connection limit logic now behaves correctly under KDB-X CE.
2) Runtime script update for realtime stack
Change:
- Removed discovery process from realtime start helper.
File:
backend-q/docker/torq-realtime.sh
Current realtime helper starts:
stp1 sctp1 feed1 gateway1
3) Install scripts moved under backend-q
Moved:
install_kdb.sh->backend-q/install_kdb.shinstalltorqapp.sh->backend-q/installtorqapp.sh
Adjusted:
backend-q/Dockerfilecopy paths updated accordingly.
4) Finance Starter Pack setenv.sh CA bundle fix
Issue:
- Legacy script downloaded
cacert.pmand exported it as CA bundle. - That caused OpenSSL certificate load errors.
Fix in app script:
- Prefer existing CA bundle from env/system.
- Fallback download uses
https://curl.se/ca/cacert.pem.
File:
backend-q/TorQ-Finance-Starter-Pack/setenv.sh
Important deployment note:
- In container,
/opt/backend-q/deploy/bin/setenv.shmay be a copied stale file. - Local compose now mounts deploy-aware wrapper to that path.
5) Local deploy-aware setenv wrapper
Added:
backend-q/docker/setenv-deploy.sh
Purpose:
- Enforces deploy path variables (
TORQHOME,KDBAPPCODE, etc.) - Creates log directory safely
- Applies corrected CA bundle behavior
Mounted by local compose:
localhost-docker-compose.yaml
6) Local TLS file preparation for q websocket client
Added:
backend-q/docker/prepare_q_tls.sh
Purpose:
- Splits cert bundle into:
server-key.pemserver-crt.pemcacert.pem
Added Make target:
make -C backend-q prep-tls
Local compose mounts these to:
/usr/lib/ssl/server-key.pem/usr/lib/ssl/server-crt.pem/usr/lib/ssl/cacert.pem
7) Websocket feed implementation
Primary file:
backend-q/TorQ-Finance-Starter-Pack/code/tick/feed_ws.q
Capabilities now:
- Uses q websocket client handshake API (not
hopenws shortcut) - Works with two sockets in one process:
- trades:
/ws/us - quotes:
/ws/us-quote
- trades:
- Handle-based routing via
.z.w - Subscribes after per-socket
200 Authorized - Publishes to TorQ tables:
tradequote
- Publishes side-channel raw table for provider timestamp preservation:
eodwsraw
Schema update:
- Added
eodwsrawinbackend-q/TorQ-Finance-Starter-Pack/database.q
Side-Channel Table
Added table:
eodwsraw
Goal:
- Keep provider timestamp (
t) exactly, alongside normalized fields and raw payload text.
Fields:
time(ingest timestamp)providerts(converted from provider epoch ms)symkind(trade/quote)price,bid,ask,size,bsize,asizerawsrc
Commands
Build / run local torq service
From repo root:
docker compose -f localhost-docker-compose.yaml up -d torq
Prepare local TLS files
make -C backend-q prep-tls
TorQ process summary
make summary-backend-q
Enter torq container shell
docker exec -it sravz-torq-1 bash
Start websocket feed process manually
Inside container:
source /opt/backend-q/deploy/bin/setenv.sh
q "$TORQHOME/torq.q" -proctype feed -procname feed_ws1 -p 6098 -debug -noredirect -trap -load "$KDBAPPCODE/tick/feed_ws.q"
Known good direct handshake probe (inside container)
.z.ws:{0N!"ws msg";0N!x;}
req:"GET /ws/us?api_token=demo HTTP/1.1\r\nHost: ws.eodhistoricaldata.com:443\r\n\r\n"
res:.[{[u;r] u r};(`$":wss://ws.eodhistoricaldata.com:443";req);{[e] e}]
show type res
show res
Common Troubleshooting Notes
/torq.q. OS reports: No such file or directory
Cause:
TORQHOMEunset in shell.
Fix:
- source setenv, or use absolute path.
connection failed: type / websocket open issues
Cause:
- Wrong argument type or connection form.
Fix:
- Use q websocket handshake API:
(`$":wss://host:443") "GET ..."
X509_load_cert_crl_file_ex:no certificate or crl found
Cause:
- Invalid CA file path/content (historically from
cacert.pm).
Fix:
- Ensure
SSL_CA_CERT_FILEpoints to a real PEM bundle. - Use corrected deploy setenv and mounted CA bundle.
TorQ logger type failures
Cause:
- Passing list/mixed types instead of single char vector in
.lg.*message.
Fix:
- Flatten log text before
.lg.o/.lg.ecalls.
onmsg failed: rank
Cause:
- Trap function arity mismatch in
.[f;args;e].
Fix:
- Ensure
flambda arg list matches passed args exactly.
EOD subscribe validation errors
Observed:
Action and symbols should be string
Fix:
- Send:
{"action":"subscribe","symbols":"AMZN,TSLA"}
Quote endpoint payload shape
Confirmed /ws/us-quote payload keys:
s,ap,as,bp,bs,t
Current quote mapper supports these aliases and common alternates.
Scaling Guidance (600 tickers)
Provider constraint:
- 50 tickers per websocket connection.
Recommendation:
- Minimum 12 connections for 600 symbols.
- Prefer 14-16 connections for headroom and rebalance.
- Shard symbols deterministically across sockets.
- Run multiple feed processes (not one giant process) for isolation.
For a full feed handler design, see:
docs-hugo/content/docs/Tech/kdb/feed_handler.md
9) TorQ Main Components: What To Say In Interviews
Use this section when asked, “How do the major TorQ processes work together?”
| Component | Primary responsibility | Key functions/messages you should mention | Recovery role |
|---|---|---|---|
feed1 | Ingest market/test events and send to TP | Sends update payloads to TP (.u.upd path) | Producer only; does not own TP log |
stp1 (segmented TP) | Central ordered pub/sub + TP logging | .u.tick, .u.upd, .u.pub, .u.sub, .u.end; TP counters .u.i/.u.j/.u.L/.u.l | Core recovery backbone (journal source-of-truth) |
sctp1 (chained TP) | Fanout isolation / downstream TP tier | Subscribes upstream, republishes downstream (.u.pub pattern) | Limits blast radius; can replay from upstream TP logs |
rdb1 | Intraday in-memory state + low-latency queries | upd:insert, .u.sub to TP, .u.rep bootstrap, .u.end EOD handler | Reconnect -> replay TP log -> resume live |
wdb1 | Write buffer/workflow staging toward persistence | Batch/write orchestration helpers (app-specific) | Reduces pressure on hot path during flush windows |
sort1 | Sort orchestration for write pipelines | Coordinates sort jobs before/around persistence | Improves deterministic write ordering for downstream storage |
sortworker1/2 | Parallel sort execution | Worker jobs from sort1 | Throughput support for EOD/intraday write workflows |
hdb1/hdb2 | Historical query serving | Loads partitioned/splayed data, shared sym domain | Durable history after EOD writedown |
gateway1 | Client query routing | Routes queries to RDB/HDB and merges results | Query continuity during component restarts |
tpreplay1 | Controlled TP log replay process | Replays TP logs to rebuild state | Main operational replay utility |
discovery1 | Service registration/discovery | Process registration + endpoint lookup | Faster, safer restart wiring |
housekeeping1 | Background maintenance | Rotation/cleanup/maintenance tasks | Keeps logs/ops hygiene stable |
metrics1 | Metrics/observability emission | Health/latency/lag metric publishing | Detects replay lag and recovery health |
monitor1 (optional) | Health supervision/alerting | Process/heartbeat checks | Faster failure detection |
reporter1 (optional) | Scheduled reporting/check jobs | Batch report triggers and checks | Post-recovery business validation workflows |
filealerter1 (optional) | File-triggered eventing | Watch file arrivals/changes and trigger jobs | Supports file-based reconciliation/replay triggers |
dqc* / dqe* (optional) | Data-quality control/engine processes | Validation and rule execution stacks | Validates recovered state quality |
10) Mental model
Use this section to explain TorQ as a resilient, decoupled data pipeline in interviews.
10.1 Unifying pitch: The resilient conveyor belt
“TorQ organizes kdb+ as an asynchronous conveyor belt. Components are decoupled so that a crash, query spike, or downstream slowdown does not stall front-door market data ingestion.”
10.2 Component value and mental anchors
| Component | How it helps in production | Mental model anchor |
|---|---|---|
feed1 | Isolates external protocol/network volatility (FIX/WebSocket/JSON) from core data state. Feed restarts do not force full stack restart. | Port of Entry |
stp1 (segmented TP) | Central ordered journal + pub/sub core; persists updates in sequence for deterministic recovery. | Master Ledger |
sctp1 (chained TP) | Absorbs fan-out and replication load so primary TP does not saturate under subscriber spikes. | Satellite Repeater |
rdb1 | In-memory intraday query surface for low-latency analytics and strategy reads. | Active Workbench |
wdb1 | Handles write/staging pressure so real-time query/ingest path stays responsive. | Staging Dock |
sort1, sortworker1/2 | Parallelizes sort/prepare stages for EOD or heavy write pipelines. | Sorting Crew |
hdb1/hdb2 | Durable historical store for large retrospective analysis over partitioned/splayed data. | Archive Warehouse |
gateway1 | Single client entrypoint that routes/merges RDB + HDB paths and hides backend complexity. | Concierge Desk |
tpreplay1 | Rebuilds process state from TP logs after failure using controlled replay workflows. | Crash Reconstructionist |
discovery1 | Dynamic registration and endpoint lookup; removes brittle hardcoded wiring. | Dynamic Switchboard |
housekeeping1 | Rotates/cleans operational artifacts to avoid avoidable disk/workspace failures. | Janitorial Staff |
metrics1, monitor1 | Continuous health and lag visibility with alerting for early failure detection. | Control Room + Alarms |
reporter1, filealerter1 | Event-driven/scheduled operational workflows (reports, file-triggered jobs). | Gate Guard + Courier |
dqc*, dqe* | Data quality controls before persistence/consumption to prevent polluted datasets. | Border Inspector |
10.3 Interview close
“TorQ scales by separation of concerns: ingest and journaling are protected, fan-out is isolated, real-time analytics stay in memory, history is persisted separately, and replay/observability provide operational resilience.”
