BDOBBSecretoftheUniverse.com
Live cache · kdb+/q In the backend stack You supply q under KX's licence

The tick store trading desks run on, under your dashboard.

BDOBB's backend stack, openbb-docker, keeps the live trading session in kdb+ and its language q. KX describes kdb+ as the engine "the world's fastest trading firms have run on for 30 years", and says its surveillance product built on kdb+ is "used extensively in high-frequency, electronic trading". Every update is appended to a tickerplant-style log before it reaches memory. When the process restarts, q replays that log, so the cache comes back with every update it had accepted.

O(1)one log append per update
-11!q's streaming replay on boot
7 daysof daily logs kept on disk
Delta Lakewhere each finished day is written
The standard shape

kdb+tick, the layout KX documents for real-time data.

A "vanilla" tick setup has a tickerplant logging to disk and publishing to an in-memory real-time database (RDB). At day end, the RDB's data is saved as another day in the historical database (HDB). Click any box to see what it does in the standard design and what plays that role in this stack.

Tickerplant

Standard kdb+tick

In this stack

Side by side

Same durability contract, fewer moving parts.

The stack keeps the parts of kdb+tick that make a restart lossless: an append-only log, replay with -11!, and a daily roll. It folds the tickerplant and the RDB into a single q process, and it sends finished days to Delta Lake rather than to a q HDB.

ConcernStandard kdb+tick (KX)BDOBB backend stack
Write pathThe tickerplant's .u.upd publishes the message, writes it to the log, and increments .u.i (tick.q).upd is wrapped once. Each update is appended to the log, then inserted into trades and pushed to WebSocket subscribers.
Log fileOne file per day, <dir>/<schema><date>, held in .u.L. KX advises a fast local disk./data/logs/tlog_YYYY.MM.DD, one O(1) append per update. This replaced an earlier full-table mirror written every 5 minutes.
RecoveryThe RDB asks the tickerplant for the schema, the log location and the message count, then replays that many chunks with -11! (r.q).At boot, q replays every log on disk, oldest first, with -11!. It replays only into an empty table, so reloading the script into a running server doesn't duplicate rows.
Day roll.u.endofday calls each subscriber's .u.end and starts a new log.A 60-second timer starts a new log when the UTC date changes and deletes logs older than 7 days.
HistoryThe RDB writes a date partition to the HDB at end of day.A sidecar writes each finished day to Delta Lake, one table per symbol and date, overwriting the whole table so a re-run is safe. Charts read completed periods from that tick vault.
Real-time analyticsRTEs compute on every update, such as order books and latest prices, and should finish within the publish interval.Served over WebSocket: a 500-tick snapshot on subscribe, OHLCV and VWAP bars of any width, anchored VWAP by time or trade count, as-of joins and memory stats.
ExposureGateways route queries and return sensible errors.q listens only on 127.0.0.1. The HTTP handler serves two read-only paths and replaces q's default handler, which can run code.
Restart drill

Kill the process.
Watch the log bring it back.

This simulation runs in your browser and mirrors the boot sequence in openbb-docker's persist.q. Let a few ticks arrive, kill q, then restart it. Then kill it again, corrupt the tail of the log, and restart to see KX's standard repair. Counts and byte sizes are illustrative.

Feed
0updates sent
q memory · trades
0rows · process up
Disk · tlog_2026.10.13
0chunks · 0 bytes

      

The drill covers what the log covers: updates q accepted before it stopped. What a feed does while q is down depends on the feed, so the drill pauses it.

Standard recovery

How kdb+ shops bring a real-time database back.

These are KX's own procedures, from its kdb+tick source and its documentation on log files and disaster recovery.

1

Ask the tickerplant where to start

A restarted RDB is empty. Its first act is a single synchronous call that subscribes and returns the table schemas plus the log's message count and file name. KX's r.q does it in one line:

.u.rep .(hopen `$":",.u.x 0)"(.u.sub[`;`];`.u `i`L)";
2

Replay exactly that many messages

.u.rep creates the tables, then streams the log through -11!. Each chunk is evaluated as it is read, so replay doesn't load the whole file into memory. KX's architecture guide says the log "is used for recovery: if the RDB has to restart, the log file is replayed to return to the current state."

.u.rep:{(.[;();:;].)each x;if[null first y;:()];-11!y;system "cd ",1_-10_string first reverse y};
3

Let queued updates drain, and route queries elsewhere

Updates published during the replay wait in the TCP buffer and then in tickerplant memory, visible in .z.W. In extreme cases this can cause a wsfull error. Replay can take minutes or more, so the gateway keeps sending queries to the secondary until the primary is ready (KX, disaster-recovery planning).

4

If the tail is corrupt, keep the valid part

A plain replay of a damaged file signals 'badtail. -11!(-2;file) returns the number of valid chunks and the length of the valid part. You then rebuild a good log from those chunks, or copy the first N bytes with head -c. KX notes this "does not fix the corrupted section, only removes" it (KX, log files).

q)-11!(-2;logfile)
26
35634
goodfile:hsym `:good.log; goodfile set ();
goodfilehandle:hopen goodfile;
chunks:first -11!(-2;`:bad.log);
.z.ps:{goodfilehandle enlist x};
-11!(chunks;`:bad.log);
system"x .z.ps"; hclose goodfilehandle;
The same idea in this stack, from persist.q
/ wrap upd exactly once: append to the log, then the original insert+publish
if[not `updCore in key `.; updCore:upd];
upd:{[t;d] if[not null .tlog.h; .tlog.h enlist(`upd;t;d)]; updCore[t;d]};

/ boot replay: every log still on disk, oldest first. Hot-load guard.
if[not count trades;
  {[f] -1 "tlog: replaying ",string f; -11! ` sv .tlog.dir,f} each asc key .tlog.dir];

The log handle is still null during the replay, so replayed updates are not written to the log a second time. The day's log is opened only after the replay finishes.

Disaster recovery

What production kdb+ sites add on top.

KX's disaster-recovery white paper describes the practices capital-markets sites layer on top of log replay. Each card shows where this stack stands today.

Hot-hot secondary

Not in this stack

A full mirror of the feedhandler, tickerplant and subscribers on separate infrastructure, with its own file system, that can take over when anything critical goes down.

Failover on disconnect

Not in this stack

Subscribers get a closed-connection callback in .z.pc and use it to switch to the secondary tickerplant. Afterwards, reconcile the primary and secondary.

Dedicated log drives

Your hardware

Tickerplant logs belong on fast, dedicated drives with no contention, to keep publishing fast and replay short. Here, that depends on where you mount /data.

Back up logs and the sym file

Partly

KX stresses backing up tickerplant logs as well as the database, and the HDB sym file in particular. Here, logs stay on disk for 7 days and finished days are written to Delta Lake, which has no q sym file.

Lossless restart

In the stack

Replay the log at startup to rebuild memory exactly. This is the core of kdb+tick, and here it covers every day still on disk, not only today.

Capacity headroom

Reference

KX cites up to 4.5 million streaming records per second per core, or 10 million with batching. Its RDB sizing rule is expected messages × schema cost × a flexibility ratio, commonly 1.5.

Not yet in this stack. No mirrored secondary site, and no automatic failover. A corrupt log tail isn't repaired at boot: the 'badtail error stops the boot replay until someone runs the KX repair. The tickerplant and the RDB run as one process, so a crash takes down the write path and the cache together.
What it adds

An addition to your OpenBB setup, not a replacement.

  • A live session you don't lose. The intraday cache survives a restart, an upgrade or a container rebuild, because the log on disk is the record of every update.
  • Trading-desk primitives on the wire. Bars of any width, VWAP from any anchor, and as-of joins are computed where the ticks live, rather than in the browser.
  • History without a q licence for every reader. Finished days go to Delta Lake, an open Apache-2.0 format, which any reader can query.
  • Your licence, your binary. The repository ships no kdb+. You install kdb-x or kdb+ Personal Edition from KX and mount your own licence file.
Where BDOBB 10.0.0 meets it. BDOBB 10.0.0 draws a live grid as a streaming table card: a snapshot over HTTP, then each row ticks in place over the widget's websocket. It pairs with openbq-docker v10, whose opt-in live profile runs the live-grid sidecar with this kdb+ cache, vendored as openbq-kdb 10.0.0 from Adventures-OpenBQ/openbq-kdb. Finished days go to Delta Lake on RustFS, and live-grid reads them back. Live checks against a running stack are still to be run on the Mac.

Sources

kdb+, q, KDB-X and KX are trademarks of KX Systems, Inc. BDOBB and SecretoftheUniverse.com LLC are not affiliated with or endorsed by KX. The kdb+ binary and licence come from KX under KX's terms.