> ## Documentation Index
> Fetch the complete documentation index at: https://whatsapp-rust.jlucaso.com/llms.txt
> Use this file to discover all available pages before exploring further.

# June 9, 2026 — GroupInfo: derived PN→LID index, smaller cache and disk footprint

> The pn_to_lid_map reverse index is now derived and skipped during serialization, roughly halving LID-group mapping bytes in memory and on disk. Breaking: lid_jid_for_phone_user is renamed to lid_user_for_phone_user and returns Option<&CompactString> instead of Option<&Jid>.

## Performance

**`GroupInfo`: reverse PN→LID index derived and no longer persisted ([#810](https://github.com/oxidezap/whatsapp-rust/pull/810))**

`GroupInfo` (in `wacore`) previously kept two parallel maps — `lid_to_pn_map` (LID user → phone `Jid`) and `pn_to_lid_map` (phone user → LID `Jid`) — and both were serialized into every `group_metadata` cache blob. Because `pn_to_lid_map` is a pure function of `lid_to_pn_map`, this doubled the mapping bytes in both the in-memory 250-entry TTL cache and on disk.

The reverse index is now:

* **`HashMap<CompactString, CompactString>`** (LID user string stored inline, not a `Jid`).
* **`#[serde(skip)]`** — absent from serialized `group_metadata` blobs. Old blobs that carry `pn_to_lid_map` still decode correctly; `serde_json` ignores the unknown field and the index is rebuilt from the forward map on deserialize.
* **Rebuilt on deserialize** via a `GroupInfoDe` shadow struct, so `query_info` warm-cache lookups always have a valid reverse index without any extra I/O.

For a large LID group this roughly halves the serialized mapping section in `group_metadata`.

## Breaking changes

**`lid_jid_for_phone_user` → `lid_user_for_phone_user`, returns `Option<&CompactString>`**

```rust theme={null}
// Before
let lid_jid: Option<&Jid> = info.lid_jid_for_phone_user("15551234567");

// After — returns the LID user string; reconstruct the Jid on demand if needed
let lid_user: Option<&CompactString> = info.lid_user_for_phone_user("15551234567");
if let Some(u) = lid_user {
    let jid = Jid::lid(u.clone());
}
```

The sole internal consumer (`phone_device_jid_into_lid`) reconstructs the `Jid::lid` on demand — the new API avoids pre-allocating N `Jid`s per `GroupInfo` build while keeping the same behaviour for callers.

**`lid_to_pn_map()` accessor removed**

The `lid_to_pn_map() -> &HashMap<CompactString, Jid>` method had zero external callers and is removed. Use `phone_jid_for_lid_user(lid_user)` to look up individual entries.
