The protocol supports both regular socket and WebSocket transport layers for sending and receiving messages. The transport layer is versioned along with the rest of the data protocol and is responsible for:
- Negotiating Neo4j protocol version
- Establishing and terminating sessions
- Routing messages from clients to specific sessions and back
Sessions
Each connection to the server creates a new session that lives until that connection is closed. Each session is isolated and the server keep track of the current state, based on the requests and responses exchanged within that session.
Neo4j uses sticky sessions, which means that, in a database cluster, each session is tied to one specific Neo4j instance.
Connecting
To begin a new session, the client connects using either a regular socket or a WebSocket. Once connected, both transport layers can be treated identically.
If Neo4j has been configured to enable encryption, TLS
, the connections need to be made using a secure socket or a secure WebSocket.
A regular socket connection should be made to the host and port Neo4j has been configured to use for its regular socket listener. The default port for regular socket connections is 7687. Similar configuration exists for the WebSocket listener. The default port for WebSocket connections is 7688.
Important If TLS is enabled, and no certificate has been specified, Neo4j will automatically generate a self-signed
TLS certificate. It is vital that your database driver not simply accept any certificate without validating it. If
you do not verify the certificate it is very simple to bypass the encryption. You should either ensure you have a
valid signed certificate installed with Neo4j or that your application implements |
Handshake
After connecting, a handshake takes place to establish which Bolt protocol version should be used for that connection. This handshake is a version-independent mini-protocol which is guaranteed to remain the same, regardless of preferred or available protocol versions.
In the handshake, the client fist sends a magic four byte preamble (6060 B017) followed by four protocol versions it supports, in order of preference.
The proposal is always represented as four 32-bit unsigned integers.
Each integer represents a proposed protocol version to use, or zero (00 00 00 00
) for "none".
The server will respond with a single 32-bit unsigned integer representing the chosen protocol.
This will always represent the highest-priority protocol version the server supports.
If none of the proposed protocols are supported, the server responds with zero (00 00 00 00
) and closes the connection.
Initial handshake
Client: <connect> Client: 60 60 B0 17 Client: 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 # Version 1 None None None Server: 00 00 00 01 # Choose # version 1
No supported version
Client: <connect> Client: 60 60 B0 17 Client: 00 00 00 06 00 00 00 00 00 00 00 00 00 00 00 00 # Version 6 None None None Server: 00 00 00 00 # None # supported Server: <disconnect>
Message framing
The transport protocol uses a framing layer to wrap messages.
Each message is transferred as one or more chunks
of data.
Each chunk starts with a two-byte header, an unsigned big-endian 16-bit integer, representing the size of the chunk not including the header.
A message can be divided across multiple chunks, allowing client and server alike to transfer large messages without having to determine the length of the entire message in advance.
Each message ends with two bytes with the value 00 00
, these are not counted towards the chunk length.
A message in one chunk
Chunk size: 16 Message data: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00 10 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00 00 chunk | Message | End header | Data | Marker
A message split in two chunks
Chunk size: 16 Message data: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 01 02 03 04 00 10 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00 04 01 02 03 04 00 00 chunk1 | Message | chunk2 | Message | End header | Data | header | Data | Marker
Two messages
Chunk size: 16 Message 1 data: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F Message 2 data: 0F 0E 0D 0C 0B 0A 09 08 00 10 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00 00 chunk | Message 1 | End header | Data | Marker 00 08 0F 0E 0D 0C 0B 0A 09 08 00 00 chunk | Message 2 | End header | Data | Marker
Disconnecting
A session ends when its communication socket is closed. Typically, this will be closed by the client.