> For the complete documentation index, see [llms.txt](https://adatrack.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://adatrack.gitbook.io/docs/documentation/iot-ingestion/udp-protocol.md).

# UDP Protocol

AdaTrack prioritizes the **User Datagram Protocol (UDP)** for telemetry ingestion due to its minimal overhead, which is critical for battery-powered IoT devices and unreliable network environments.

### The UDP Advantage

While TCP provides reliability through handshakes and acknowledgments, these mechanisms introduce significant data overhead and power consumption. For many IoT sensors, the TCP handshake can be larger than the actual data being sent.

UDP allows for a "fire-and-forget" model:

* **Lower Latency:** No connection setup or teardown.
* **Lower Bandwidth:** Minimal header size (8 bytes).
* **Power Efficient:** Radio remains active for a shorter duration.

### Device Endpoint

Send UDP packets to the following address:

| Deployment             | Host                           | Port                                       |
| ---------------------- | ------------------------------ | ------------------------------------------ |
| **SaaS (adatrack.io)** | `ingest.adatrack.io`           | `9000`                                     |
| **Self-hosted**        | Your configured hostname or IP | Your configured UDP port (default: `9000`) |

> **Note:** The ingestion endpoint is not proxied — DNS resolves directly to the server. There is no HTTP layer; all packets are raw UDP.

### Data Packet Structure

While your specific payload is flexible (decoded via [Custom Decoders](/docs/documentation/iot-ingestion/decoders.md)), AdaTrack recommends a standard envelope for secure and reliable transmission:

| Field         | Size     | Description                                                       |
| ------------- | -------- | ----------------------------------------------------------------- |
| **Device ID** | 16 Bytes | Unique identifier (UUID).                                         |
| **Timestamp** | 8 Bytes  | UNIX Epoch (Big Endian). Used for ordering and replay protection. |
| **Payload**   | Variable | Your proprietary binary sensor data.                              |
| **Signature** | 32 Bytes | HMAC-SHA256 signature for authentication.                         |

### Ingestion Pipeline

When a UDP packet arrives at our ingestion endpoint (`ingest.adatrack.io`, Port `9000`):

1. **Kernel Ring Buffer:** The packet is read from the Linux kernel ring buffer. Our servers are tuned with large `rmem` buffers to absorb micro-bursts of traffic.
2. **HMAC Verification:** The backend fetches the device's shared secret and verifies the `Signature`. If the signature is invalid or the `Timestamp` is too old (> 5s), the packet is rejected.
3. **Decoding:** The `Payload` bytes are passed to the [Goja JS VM](/docs/documentation/iot-ingestion/decoders.md) for processing.
4. **Storage & Distribution:** The resulting JSON is stored in **TimescaleDB** and broadcast to connected **WebSockets** for real-time map updates.

### Network Configuration (Self-Hosted)

If you are hosting your own AdaTrack instance, ensure your network and OS are optimized:

* **Firewall:** Allow incoming UDP traffic on your configured ingestion port (Default: `9000`).
* **Kernel Tuning:** Increase the maximum receive buffer size to prevent packet loss during high traffic.

  ```bash
  sysctl -w net.core.rmem_max=26214400
  ```
* **Worker Pools:** Configure the backend worker pool size based on your CPU cores to ensure parallel HMAC and decoding processing.

### Reliability over UDP

Since UDP is connectionless, it does not guarantee delivery. AdaTrack handles this at the application layer:

* **Idempotency:** We use the device-provided timestamp to ensure that duplicate or out-of-order packets do not corrupt your historical data.
* **Sequence Tracking:** The system can detect missing packets by analyzing the gaps in received timestamps.
