# What IPC Protocol Does OpenLogi Use for Inter-Process Communication?

> Discover the IPC protocol OpenLogi uses: tarpc with bincode serialization over local sockets for seamless GUI agent communication. Learn more about OpenLogi's efficient inter-process communication.

- Repository: [Xuan Zhang/OpenLogi](https://github.com/AprilNEA/OpenLogi)
- Tags: internals
- Published: 2026-08-31

---

**OpenLogi uses tarpc (an RPC framework) with bincode serialization over interprocess local sockets for all inter-process communication between its GUI components and background agent.**

The **OpenLogi** logistics platform implements a modular architecture where the desktop client, overlay UI, and CLI tools must coordinate with a persistent background agent. This article breaks down the exact IPC protocol stack powering that communication, based on the source code in `AprilNEA/OpenLogi`.

## The Core IPC Protocol Stack: tarpc + bincode + interprocess

OpenLogi's IPC design centers on three layered technologies working together:

- **tarpc** — A Rust-native RPC framework that provides strongly-typed remote procedure calls
- **bincode** — A compact binary serialization format for encoding messages
- **interprocess** — A cross-platform crate providing local socket (Unix domain sockets / Windows named pipes) transport

As documented in both the workspace [`AGENTS.md`](https://github.com/AprilNEA/OpenLogi/blob/main/AGENTS.md) and [`crates/openlogi-ipc/AGENTS.md`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-ipc/AGENTS.md), "the GUI and agent speak **tarpc** over **bincode** on an `interprocess` local socket". This stack lives in the dedicated `openlogi-ipc` crate, shared by all components.

## Key Implementation Files

Understanding the protocol requires examining four critical source files:

| File | Purpose |
|------|---------|
| [`crates/openlogi-ipc/src/ipc.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-ipc/src/ipc.rs) | Defines the **tarpc service contract** via `#[tarpc::service]` macro and shared wire types |
| [`crates/openlogi-ipc/src/transport.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-ipc/src/transport.rs) | Builds the layered transport: local socket → tarpc's `serde_transport` → **bincode** codec |
| [`crates/openlogi-ipc/src/client.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-ipc/src/client.rs) | Exports the `connect()` helper that establishes the tarpc connection (line 53) |
| [`crates/openlogi-ipc/AGENTS.md`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-ipc/AGENTS.md) | Protocol documentation describing the tarpc/bincode design |

## Connecting to the Agent: A Minimal Client Example

The following Rust example demonstrates how OpenLogi's desktop UI or CLI tools establish IPC communication with the agent:

```rust
use openlogi_ipc::client::{self, ConnectError, Connection};
use openlogi_ipc::ipc::AgentClient; // generated by #[tarpc::service]
use tarpc::context;

#[tokio::main]
async fn main() -> Result<(), ConnectError> {
    // 1️⃣ Establish a tarpc‑bincode connection over the local socket
    let conn: Connection = client::connect().await?;

    // 2️⃣ Split the connection into a client handle
    let (client, _) = conn.split();

    // 3️⃣ Create a typed client (the generated stub)
    let mut agent = AgentClient::new(client, context::current());

    // 4️⃣ Call a remote method, e.g. `list_devices`
    let devices = agent.list_devices(context::current()).await?;
    println!("Devices reported by the agent: {:#?}", devices);

    Ok(())
}

```

Key implementation details from this pattern:

- `client::connect()` wraps the raw `interprocess` socket in a tarpc transport layer
- `AgentClient` is generated from the `#[tarpc::service]` macro defined in [`src/ipc.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/ipc.rs)
- All parameters and return values pass through **bincode** serialization as configured in [`src/transport.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/transport.rs)

## Why This IPC Protocol Stack?

OpenLogi's choice of **tarpc with bincode over local sockets** delivers specific advantages for a desktop logistics application:

- **Type safety** — The `#[tarpc::service]` macro generates client/server stubs at compile time, eliminating wire protocol mismatches
- **Performance** — Bincode's zero-copy deserialization and compact binary format minimize latency for frequent agent queries
- **Cross-platform portability** — The `interprocess` crate abstracts Unix domain sockets and Windows named pipes behind a unified API
- **Rust-native ergonomics** — Async/await support integrates cleanly with Tokio, which OpenLogi uses throughout its stack

## Summary

- OpenLogi's **IPC protocol** combines **tarpc** RPC, **bincode** serialization, and **interprocess** local sockets
- The implementation lives in the `openlogi-ipc` crate, shared between agent and all client components
- Service contracts are defined via `#[tarpc::service]` in [`src/ipc.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/ipc.rs)
- Transport construction happens in [`src/transport.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/transport.rs) with bincode codec selection
- Client connection helpers reside in [`src/client.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/client.rs)

## Frequently Asked Questions

### Does OpenLogi use gRPC or another standard protocol for IPC?

No. According to the OpenLogi source code, the project explicitly uses **tarpc** rather than gRPC or Cap'n Proto. The maintainers chose tarpc for its native Rust integration and simpler service macro ergonomics. Bincode replaces Protocol Buffers as the serialization layer.

### What transport does OpenLogi use for local IPC?

OpenLogi uses the **`interprocess` crate** to provide local sockets—Unix domain sockets on Linux/macOS and named pipes on Windows. This is wrapped by tarpc's `serde_transport` abstraction, as implemented in [`crates/openlogi-ipc/src/transport.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-ipc/src/transport.rs).

### Is the IPC protocol in OpenLogi compatible across different versions?

The **tarpc service contract** in [`src/ipc.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/ipc.rs) defines the versioned interface. Since bincode does not provide built-in schema evolution like Protocol Buffers, OpenLogi likely requires matching versions between agent and clients. The shared `openlogi-ipc` crate ensures both sides compile against identical definitions.

### How does the OpenLogi CLI communicate with the running agent?

The CLI imports `openlogi_ipc::client::connect()` (from [`src/client.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/client.rs)) to establish a tarpc connection over the local socket, then uses the generated `AgentClient` stub to invoke methods. This identical pattern is used by the desktop GUI and overlay components.