Remote Framebuffer, or RFB, is the protocol spoken by VNC viewers and servers. It describes how two endpoints agree on security, exchange framebuffer rectangles, and carry keyboard and pointer events. It does not prescribe a desktop environment or operating system, which is why implementations can interoperate across different platforms.
What does RFB define?
RFB presents the server as a rectangular array of pixels. The viewer asks for updates, receives changed regions, draws them, and sends input events in the other direction. Version 3.8 is documented in RFC 6143, section 6.
The protocol is stateful and normally runs over TCP. Port 5900 is conventionally display :0, 5901 is :1, and so on. That convention is deployment practice rather than a requirement of RFB. A WebSocket gateway can carry the byte stream elsewhere (websockify source).
RFB messages use network byte order. Pixel bytes follow the negotiated pixel format, which describes bits per pixel, depth, endianness, true-color fields, and channel shifts. A client can request a format better suited to its display with SetPixelFormat. Correct negotiation prevents red and blue channels from being swapped or rows from being decoded at the wrong stride.
How does the RFB handshake work?
The server first sends a 12-byte version banner such as RFB 003.008\n. The client replies with the version it will use. For RFB 3.8, the server lists supported security types, the client selects one, and the chosen authentication exchange follows. A SecurityResult reports success or failure.
Server -> Client ProtocolVersion "RFB 003.008\n" Client -> Server ProtocolVersion "RFB 003.008\n" Server -> Client SecurityTypes [None, VNC Authentication, ...] Client -> Server SecurityType selected type Server <-> Client authentication exchange Server -> Client SecurityResult OK or failed On success: Client -> Server ClientInit shared-flag = 1 Server -> Client ServerInit width, height, pixel format, name
ClientInit contains a shared flag. A true value asks the server to preserve other clients; false permits the server to disconnect them according to policy. ServerInit supplies framebuffer dimensions, the initial pixel format, and a desktop name. Only after initialization do normal client and server messages begin.
RFC 6143, section 7.2.2, specifies that VNC Authentication passwords are truncated to eight characters. It describes this authentication as cryptographically weak and not intended for use on untrusted networks.
Read the connection from top to bottom. Normal-operation messages illustrate directions, not a fixed timeline. Updates repeat; input and clipboard messages can interleave.
Connection and initialization
- ProtocolVersionServer to viewerServer version
- ProtocolVersionViewer to serverVersion chosen
- Security type negotiationServer to viewerSupported types
- Security type negotiationViewer to serverType selected
- Authentication exchangeViewer and serverIf the selected type requires it
- SecurityResultServer to viewerSuccess continues; failure closes the connection
- ClientInitViewer to serverShared flag
- ServerInitServer to viewerDimensions, pixel format and name
Normal operation
- SetPixelFormatViewer to serverOptional
- SetEncodingsViewer to serverOptional
- FramebufferUpdateRequestViewer to serverRequested region
- FramebufferUpdateServer to viewerPixel rectangles
- KeyEventViewer to serverKey press or release
- PointerEventViewer to serverPointer position and buttons
- ClientCutTextViewer to serverClipboard text
- ServerCutTextServer to viewerClipboard text
Text version of the sequence
Connection and initialization
- ProtocolVersion: Server to viewer. Server version.
- ProtocolVersion: Viewer to server. Version chosen.
- Security type negotiation: Server to viewer. Supported types.
- Security type negotiation: Viewer to server. Type selected.
- Authentication exchange: Viewer and server. If the selected type requires it.
- SecurityResult: Server to viewer. Success continues; failure closes the connection.
- ClientInit: Viewer to server. Shared flag.
- ServerInit: Server to viewer. Dimensions, pixel format and name.
Normal operation
- SetPixelFormat: Viewer to server. Optional.
- SetEncodings: Viewer to server. Optional.
- FramebufferUpdateRequest: Viewer to server. Requested region.
- FramebufferUpdate: Server to viewer. Pixel rectangles.
- KeyEvent: Viewer to server. Key press or release.
- PointerEvent: Viewer to server. Pointer position and buttons.
- ClientCutText: Viewer to server. Clipboard text.
- ServerCutText: Server to viewer. Clipboard text.
How do framebuffer updates work?
RFB does not fundamentally send a video stream. The viewer sends FramebufferUpdateRequest with a rectangle and an incremental flag. An incremental request means, in effect, send changes since the previous update. A non-incremental request asks for the full requested region. The server responds with a FramebufferUpdate containing one or more rectangles.
Each rectangle has a position, size, and encoding type, followed by encoding-specific data. The viewer advertises encoding preferences with SetEncodings. Raw pixel data is allowed even if it is absent from that list (RFC 6143, section 7.5.2).
Input takes a separate path. KeyEvent and PointerEvent messages travel from viewer to server. ClientCutText and ServerCutText provide basic clipboard exchange. Latency affects how quickly input results appear because the rendered response returns through framebuffer updates.
Which encodings does RFB use?
| Encoding | Purpose |
|---|---|
| Raw | Uncompressed pixels, simple to implement and expensive on bandwidth. |
| CopyRect | Tells the viewer to copy an existing framebuffer area, useful for moves and scrolling. |
| Hextile | Splits rectangles into 16 by 16 tiles and represents repeated backgrounds and subrectangles compactly. |
| Tight extension | Community extension, not in RFC 6143. Combines filters, compression, fills, and optional JPEG for varied desktop content. |
| ZRLE | Uses tiled run-length representations compressed with a persistent zlib stream. |
Encoding support and tuning differ by implementation. Tight has an optional lossy JPEG mode (community RFB specification, Tight Encoding). ZRLE uses compression without JPEG (RFC 6143, section 7.7.6).
| Implementation | Core RFB | Common encodings | TLS / VeNCrypt | Clipboard |
|---|---|---|---|---|
| TigerVNC | 3.3, 3.7, 3.8 | Raw, CopyRect, Hextile, Tight, ZRLE | TLS and VeNCrypt | Text, both directions |
| TightVNC | 3.3, 3.7, 3.8 | Raw, CopyRect, Hextile, Tight, ZRLE | No native VeNCrypt; tunnel where needed | Text, both directions |
Pseudo-encodings
Negative encoding numbers identify many extensions that change behavior rather than pixel compression (RFC 6143, section 7.8). Cursor-shape pseudo-encodings let the viewer draw the pointer locally, avoiding a round trip for every movement. Desktop-size extensions announce resolution changes. Continuous-updates extensions let a server push changes within a region without waiting for a new request after every update (community RFB specification).
Other extensions cover multiple monitors, richer input, and compression levels. Both endpoints must agree on semantics. A server ignores an unsupported pseudo-encoding, as described in the community RFB specification. RFC 6143, section 7.5.2, permits Raw pixel data even when the client did not advertise it; section 7.7.1 requires every client to handle Raw. Test the exact viewer/server pair used in production.
Check an RFB integration
RFB gives a viewer/server integration a defined message sequence to check: version 3.8 is documented in RFC 6143, section 6. A 3.8 viewer/server pair should show the ProtocolVersion, SecurityTypes, SecurityResult, ClientInit, and ServerInit sequence above. Compare a protocol trace or logs from the exact pair used in production. Features beyond pixels and basic input need extensions. Read the history of VNC for its background.
Discuss this in the community
Sources accurate as of 30 September 2026.
Open-source VNC suits personal projects and home labs. When your business depends on remote access, RealVNC Connect adds end-to-end encryption, centralised management and commercial support from the team that created VNC.