# How the On‑Disk Probe Cache Improves Device Discovery Speed in OpenLogi

> Learn how OpenLogi's on-disk probe cache speeds up device discovery by storing HID++ handshakes for instant Logitech peripheral recognition. Slash discovery latency.

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

---

**The on‑disk probe cache in OpenLogi stores serialized device capability descriptors to bypass redundant HID++ handshakes, reducing discovery latency from hundreds of milliseconds to near‑instant for cached Logitech peripherals.**

OpenLogi is an open‑source driver for Logitech HID++ devices that must query hardware capabilities during initialization. The **on‑disk probe cache** eliminates the need to repeat these costly USB interrogations on every startup by persisting probe results between sessions.

## Why Device Probing Requires Caching

Probing a Logitech device involves querying HID++ feature reports to determine DPI steps, button layouts, and firmware capabilities. Each query requires timing‑sensitive USB round‑trips that can accumulate significant latency when multiple devices are connected. Without caching, the agent repeats this entire sequence on every launch, creating unnecessary bus traffic and noticeable startup delays.

## How the On‑Disk Probe Cache Works

The cache implementation resides in [`crates/openlogi-hid/src/probe_cache.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hid/src/probe_cache.rs) and operates as a lookup table keyed by USB vendor ID, product ID, and serial number.

### Storage Format and Location

OpenLogi serializes the cache using **`bincode`** into a compact binary blob. The system stores this file in the user’s configuration directory, typically at a path like `$HOME/.config/openlogi/probe_cache.bin`. This binary format minimizes disk I/O overhead and supports fast deserialization during agent startup.

### Cache Lookup and Fallback Strategy

During device enumeration in [`crates/openlogi-device/src/inventory/probe.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-device/src/inventory/probe.rs), the agent executes the following workflow:

1. **Load** the existing cache via `ProbeCache::load()` at initialization.
2. **Match** enumerated devices against cache entries using their unique hardware identifiers.
3. **Apply** cached capabilities immediately if a valid entry exists, skipping the HID++ handshake.
4. **Probe** live hardware only when a device is new, the cache entry is missing, or the cached firmware version differs from the reported version.
5. **Persist** updated results via `ProbeCache::save()` after discovery completes.

This strategy ensures that firmware upgrades trigger automatic cache invalidation. When a device reports a different firmware or HID++ protocol version, the stale entry is discarded and replaced with fresh probe data.

## Implementation Examples

The following patterns demonstrate how to interact with the probe cache API in Rust.

*Loading the cache at startup:*

```rust
use openlogi_hid::probe_cache::ProbeCache;

// Load existing cache or initialize empty
let mut probe_cache = ProbeCache::load().unwrap_or_default();

```

*Integrating cache lookups during enumeration:*

```rust
for device in enumerated_devices {
    // Attempt to retrieve cached capabilities
    if let Some(cached) = probe_cache.get(&device.id) {
        device.apply_capabilities(cached);
    } else {
        // Perform expensive live probe only on cache miss
        let fresh = device.probe()?;
        probe_cache.insert(device.id.clone(), fresh.clone());
        device.apply_capabilities(fresh);
    }
}

```

*Persisting updates before shutdown:*

```rust
// Write binary blob to disk for next session
probe_cache.save()?;

```

## Key Source Files

- **[`crates/openlogi-hid/src/probe_cache.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hid/src/probe_cache.rs)** — Defines the `ProbeCache` struct, implements `load()` and `save()` methods, and handles bincode serialization.
- **[`crates/openlogi-device/src/inventory/probe.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-device/src/inventory/probe.rs)** — Orchestrates device enumeration, consults the cache, and falls back to live probes on cache misses.
- **[`crates/openlogi-device/src/device.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-device/src/device.rs)** — Applies cached capability descriptors to device instances during initialization.

## Summary

- The **on‑disk probe cache** persists device capability descriptors between OpenLogi sessions to eliminate redundant HID++ handshakes.
- Cache entries are keyed by USB vendor/product IDs and serial numbers, ensuring accurate device matching.
- Invalidation occurs automatically when firmware or protocol version mismatches are detected.
- Using **`bincode`** serialization minimizes disk I/O and deserialization overhead.
- The implementation reduces startup latency and decreases USB bus contention, particularly on systems with multiple Logitech peripherals.

## Frequently Asked Questions

### Where does OpenLogi store the probe cache file?

OpenLogi stores the cache as a binary blob in the user’s configuration directory, typically at `$HOME/.config/openlogi/probe_cache.bin`, using the `bincode` format for compact, fast serialization.

### When does the cache invalidate a device entry?

The cache invalidates an entry when the device reports a firmware version or HID++ protocol version that differs from the cached value, triggering a fresh live probe to capture updated capabilities.

### What Rust crate handles the probe cache serialization?

The serialization logic resides in [`crates/openlogi-hid/src/probe_cache.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hid/src/probe_cache.rs), which uses the `bincode` crate to encode capability descriptors into a binary format optimized for rapid disk I/O.

### How does the cache improve USB performance?

By reusing stored capability data instead of issuing multiple HID++ feature report queries for every device on every startup, the cache significantly reduces USB bus traffic and eliminates timing‑sensitive round‑trip delays.