Skip to content

IPC protocol details

This page describes the low-level q interprocess communication (IPC) protocol: the connection handshake, the capability bytes the two ends exchange, and the rules that decide when q compresses a message.

For debugging, not for everyday q

This page supports debugging and troubleshooting. Typical q development never touches the low-level protocol, so you don't need any of it to write q.

To see the raw byte representation of a serialized q object, use -8!object.

Handshake

  1. The client opens a socket to the server.
  2. The client sends a null-terminated ASCII string of the form "username:password\C", where \C is a single capability byte describing the client's features, such as support for compression, UUIDs, and large messages.
  3. If the server rejects the credentials, it closes the connection.
  4. If the server accepts them, it replies with a single byte: the capability level that both ends share.

Capability bytes:

Byte Features supported
0 No compression, timestamp, timespan, or UUID (v2.5)
1–2 Compression, timestamp, timespan (v2.6–2.8)
3 Compression, timestamp, timespan, UUID (v3.0)
5 Messages larger than 2 GB; vector counts of 2 billion or fewer
6 Messages larger than 2 GB; vector counts above 2 billion

Capabilities 5 and 6 don't suit the Java and C# clients

Both clients cap array length below what these capabilities allow, so their standard object models can't represent the vectors that capabilities 5 and 6 permit. Negotiate a lower capability level when either is at the other end.

Compression

q compresses an outgoing message when all of these hold:

  • The uncompressed data is larger than 2000 bytes
  • The connection isn't to localhost or 127.0.0.1
  • The connection isn't a Unix domain socket (UDS)
  • The compressed data is less than half the size of the uncompressed data

The algorithm is a variant of Lempel-Ziv. The official q Java API carries a reference implementation.

Next steps