Skip to main content

NATS

NATS uses a plain-text protocol over TCP. Each message is a verb, optional arguments, and a CRLF; payloads follow their header line and are themselves CRLF-terminated.

Protocol Operations​

OperationSent ByFormatPurpose
INFOServerINFO {json}\r\nServer details, sent on connect
CONNECTClientCONNECT {json}\r\nClient options and credentials
PUBClientPUB <subject> [reply-to] <size>\r\n<payload>\r\nPublish a message
HPUBClientHPUB <subject> [reply-to] <hdr-size> <total-size>\r\n<headers>\r\n<payload>\r\nPublish with headers
SUBClientSUB <subject> [queue-group] <sid>\r\nSubscribe to a subject
UNSUBClientUNSUB <sid> [max-msgs]\r\nUnsubscribe, optionally after a count
MSGServerMSG <subject> <sid> [reply-to] <size>\r\n<payload>\r\nDeliver a message
HMSGServerHMSG <subject> <sid> [reply-to] <hdr-size> <total-size>\r\n<headers>\r\n<payload>\r\nDeliver with headers
PINGBothPING\r\nKeepalive request
PONGBothPONG\r\nKeepalive response
+OKServer+OK\r\nAcknowledgment, when verbose is set
-ERRServer-ERR <reason>\r\nProtocol error. The server closes the connection after most of these

Subjects and Wildcards​

Subjects are dot-separated tokens. Two wildcards are available when subscribing:

WildcardMatchesExample
*Exactly one tokenlogs.*.error matches logs.auth.error
>One or more tokens, and only as the final tokenlogs.> matches logs.auth and logs.auth.error

The optional queue-group argument on SUB places subscribers into a group, and the server delivers each message to only one member—this is how load is distributed across consumers.

The CONNECT Message​

Credentials travel in the JSON payload of CONNECT, which is why the wire carries no distinct authentication verb.

FieldDescription
user, passUsername and password
auth_tokenToken authentication
jwtUser JWT for account-scoped authentication
sigSignature over the server's nonce, for NKey and JWT authentication
nkeyThe NKey public key
nameClient name
headersWhether the client understands HPUB and HMSG
verboseWhether the server should send +OK

JetStream​

JetStream is the persistence layer, and it is not a separate protocol. Its operations are ordinary request-reply exchanges over core NATS: a client publishes a JSON request to a subject under $JS.API.> and receives a JSON reply on an inbox subject. Message acknowledgment likewise publishes to the reply subject carried on the delivery.

This matters when reading the operations table above: a JetStream consumer still uses PUB, SUB and MSG on the wire.