NPC - Nano Protocol for Communication
Version: 1.0 Status: Draft Date: March 2026
NPC (Nano Protocol for Communication) is a lightweight binary protocol designed for IoT devices, sensors, and real-time messaging applications where minimal overhead and simplicity are paramount. This document specifies the protocol format, message types, and communication patterns.
- Introduction
- Protocol Overview
- Message Format
- Message Types
- Status Codes
- Flags
- Payload Format
- Communication Patterns
- Transport Layer
- Security Considerations
- Examples
NPC provides a minimal binary protocol for scenarios where HTTP's text-based headers introduce unacceptable overhead. Common use cases include:
- IoT sensor networks
- Real-time telemetry
- Embedded systems with limited bandwidth
- High-frequency message passing
- Pub/Sub messaging systems
- Minimal overhead: 8-byte fixed header vs. hundreds of bytes for HTTP
- Simplicity: Entire protocol fits on one page
- Efficiency: Binary format, no parsing overhead
- Flexibility: Supports request/response, push, and pub/sub patterns
- Language agnostic: Easy to implement in any programming language
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
All multi-byte integers are encoded in big-endian (network byte order).
NPC messages consist of a fixed 8-byte header followed by an optional variable-length payload. The header contains all routing and control information needed to process the message.
+------------------+------------------+
| Header (8B) | Payload (0-64KB)|
+------------------+------------------+
Byte: 0 1 2 3 4 5 6 7
+------+------+------+------+------+------+------+------+
| VER | TYPE | FLAGS|STATUS| SEQ ID | LEN |
+------+------+------+------+------+------+------+------+
| Field | Offset | Size | Description |
|---|---|---|---|
| VER | 0 | 1 byte | Protocol version |
| TYPE | 1 | 1 byte | Message type |
| FLAGS | 2 | 1 byte | Bit flags for options |
| STATUS | 3 | 1 byte | Response status code |
| SEQ ID | 4 | 2 bytes | Sequence ID for request/response matching |
| LEN | 6 | 2 bytes | Payload length in bytes |
- Current version:
0x01 - Future versions MUST increment this value
- Receivers SHOULD reject messages with unsupported versions
- See Section 4 for complete list
- Range:
0x01-0xFF 0x00is reserved
- Bit field for optional features
- See Section 6 for flag definitions
- Response status code
- See Section 5 for complete list
- Ignored in request messages (SHOULD be set to
0x00)
- 16-bit unsigned integer (0-65535)
- Used to match responses with requests
- Sender chooses value; receiver echoes it back
- Wraps around after 65535
- 16-bit unsigned integer
- Maximum payload size: 65535 bytes
0x0000indicates no payload
| Value | Name | Description |
|---|---|---|
| 0x00 | RESERVED | Reserved, MUST NOT be used |
| 0x01 | REQUEST | Client request requiring response |
| 0x02 | RESPONSE | Server response to a request |
| 0x03 | PUSH | Server-initiated message (no response) |
| 0x04 | PING | Connection health check request |
| 0x05 | PONG | Connection health check response |
| 0x06 | SUBSCRIBE | Subscribe to a topic/channel |
| 0x07 | UNSUBSCRIBE | Unsubscribe from a topic/channel |
Sent by a client to request data or action from the server.
- MUST include a unique SEQ ID
- Server MUST respond with a RESPONSE message using the same SEQ ID
- MAY include a payload with request parameters
Sent by a server in response to a REQUEST.
- MUST echo the SEQ ID from the corresponding REQUEST
- MUST include an appropriate STATUS code
- MAY include a payload with response data
Server-initiated message sent without a prior request.
- Used for event notifications, streaming data, pub/sub delivery
- Does NOT require a response
- If FLAGS.REQUIRES_ACK is set, client SHOULD acknowledge
Connection health check request.
- Used to verify the connection is still alive
- Receiver MUST respond with PONG
- SHOULD NOT include a payload
- MUST echo the SEQ ID in the PONG response
Response to PING.
- MUST echo the SEQ ID from the PING
- MUST be sent promptly after receiving PING
- SHOULD NOT include a payload
Request to subscribe to a topic or channel.
- Payload MUST contain the topic identifier (2-byte topic ID or topic name)
- Server responds with RESPONSE indicating success/failure
- After successful subscription, client will receive PUSH messages for that topic
Request to unsubscribe from a topic or channel.
- Payload MUST contain the topic identifier
- Server responds with RESPONSE indicating success/failure
| Value | Name | Description |
|---|---|---|
| 0x00 | OK | Request succeeded |
| 0x01 | ERROR | Generic error |
| 0x02 | NOT_FOUND | Requested resource not found |
| 0x03 | BUSY | Server is busy, try again later |
| 0x04 | UNAUTHORIZED | Authentication required |
| 0x05 | FORBIDDEN | Permission denied |
| 0x06 | TIMEOUT | Request timed out |
| 0x07 | BAD_REQUEST | Malformed request |
- Status codes are only meaningful in RESPONSE messages
- REQUEST, PUSH, PING messages SHOULD set status to 0x00
- Applications MAY define custom status codes in range 0x80-0xFF
Bit: 7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
| Reserved |ACK|CMP|
+---+---+---+---+---+---+---+---+
| Bit | Name | Description |
|---|---|---|
| 0 | COMPRESSED | Payload is compressed (algorithm TBD) |
| 1 | REQUIRES_ACK | Sender expects acknowledgment |
| 2-7 | RESERVED | Reserved for future use, MUST be 0 |
When set:
- Payload data is compressed
- Default compression: zlib/deflate
- Receiver MUST decompress before processing
When set:
- Sender expects an acknowledgment
- Used primarily with PUSH messages
- Receiver SHOULD send RESPONSE with matching SEQ ID
The payload format is application-defined, but this specification RECOMMENDS the following structure for routing:
Byte: 0 1 2 3 ... N
+------+------+------+------+------+------+
| TOPIC ID | DATA ... |
+------+------+------+------+------+------+
- TOPIC ID (2 bytes): Optional routing identifier
- DATA: Application-specific data (JSON, binary, etc.)
- 16-bit unsigned integer
0x0000indicates no specific topic (broadcast/default)- Used for message routing in pub/sub scenarios
The DATA section is entirely application-defined. Common formats include:
- Raw binary sensor readings
- JSON for structured data
- MessagePack for efficient binary serialization
- Protocol Buffers for schema-defined data
Client Server
| |
| REQUEST (seq=1) |
|------------------------------>|
| |
| RESPONSE (seq=1, status=OK) |
|<------------------------------|
| |
Client Server
| |
| (connection established) |
|<----------------------------->|
| |
| PUSH (topic=sensors) |
|<------------------------------|
| |
| PUSH (topic=sensors) |
|<------------------------------|
| |
Client Server
| |
| SUBSCRIBE (topic=temp) |
|------------------------------>|
| |
| RESPONSE (status=OK) |
|<------------------------------|
| |
| PUSH (topic=temp, data=...) |
|<------------------------------|
| |
| PUSH (topic=temp, data=...) |
|<------------------------------|
| |
| UNSUBSCRIBE (topic=temp) |
|------------------------------>|
| |
| RESPONSE (status=OK) |
|<------------------------------|
| |
Client Server
| |
| PING (seq=42) |
|------------------------------>|
| |
| PONG (seq=42) |
|<------------------------------|
| |
NPC is designed primarily for TCP transport.
- Connection-oriented, reliable delivery
- Message framing handled by header's LEN field
- Implementation MUST read exactly LEN bytes after header
- Client opens TCP connection to server
- No handshake required at NPC level
- Either party may send messages immediately
- Either party may close the TCP connection
- Clean shutdown: close socket gracefully
- No NPC-level disconnect message required
UDP transport may be used for scenarios requiring:
- Lower latency
- Connectionless communication
- Multicast support
When using UDP:
- Message size limited to MTU (typically 1500 bytes)
- Application MUST handle packet loss
- SEQ ID becomes critical for deduplication
For secure communication:
- Use TLS 1.2 or higher
- NPC messages are sent over the encrypted channel
- No modification to the protocol itself
NPC does not define authentication mechanisms. Applications SHOULD:
- Use TLS client certificates
- Implement application-level authentication in initial REQUEST
- Consider token-based authentication in payload
- Status codes UNAUTHORIZED (0x04) and FORBIDDEN (0x05) support access control
- Applications SHOULD implement per-topic authorization for pub/sub
- Use TLS for transport encryption
- Payload encryption is application-defined
- Consider hardware acceleration for constrained devices
Implementations MUST:
- Validate VERSION is supported
- Validate TYPE is recognized
- Validate LEN does not exceed buffer sizes
- Handle malformed messages gracefully
A temperature sensor sending a reading:
Header:
VER: 0x01 (version 1)
TYPE: 0x03 (PUSH)
FLAGS: 0x00 (no flags)
STATUS: 0x00 (N/A for PUSH)
SEQ ID: 0x00 0x01 (1)
LEN: 0x00 0x0A (10 bytes)
Payload:
TOPIC: 0x00 0x01 (topic 1 = temperature)
DATA: {"t":23.5} (8 bytes, JSON)
Wire format (hex):
01 03 00 00 00 01 00 0A 00 01 7B 22 74 22 3A 32 33 2E 35 7D
Client subscribing to temperature topic:
Header:
VER: 0x01
TYPE: 0x06 (SUBSCRIBE)
FLAGS: 0x00
STATUS: 0x00
SEQ ID: 0x00 0x0A (10)
LEN: 0x00 0x02 (2 bytes)
Payload:
TOPIC: 0x00 0x01 (topic 1)
Wire format (hex):
01 06 00 00 00 0A 00 02 00 01
Server confirming subscription:
Header:
VER: 0x01
TYPE: 0x02 (RESPONSE)
FLAGS: 0x00
STATUS: 0x00 (OK)
SEQ ID: 0x00 0x0A (10, matching request)
LEN: 0x00 0x00 (no payload)
Wire format (hex):
01 02 00 00 00 0A 00 00
Health check exchange:
PING:
01 04 00 00 00 2A 00 00
PONG:
01 05 00 00 00 2A 00 00
Offset Size Field
0 1 Version (0x01)
1 1 Type
2 1 Flags
3 1 Status
4 2 Sequence ID (big-endian)
6 2 Payload Length (big-endian)
0x01 REQUEST
0x02 RESPONSE
0x03 PUSH
0x04 PING
0x05 PONG
0x06 SUBSCRIBE
0x07 UNSUBSCRIBE
0x00 OK
0x01 ERROR
0x02 NOT_FOUND
0x03 BUSY
0x04 UNAUTHORIZED
0x05 FORBIDDEN
0x06 TIMEOUT
0x07 BAD_REQUEST
Bit 0 COMPRESSED
Bit 1 REQUIRES_ACK
Reference implementations are available in:
- Go (reference)
- Python
- Rust
- TypeScript/Node.js
See the project repository for implementation details.
NPC Protocol Working Group
This specification is released under CC0 1.0 Universal (Public Domain Dedication).