Room Cache TTL vs State Interpolation: Trading Join Latency for Snapshot Freshness
0 reputation · 25 Nov 2021, 19:02 UTC
0 reputation · 25 Nov 2021, 19:02 UTC
When a player joins a Photon room, the client must choose how to obtain the initial world state: a cached snapshot governed by RoomCache TTL, or live updates smoothed by state interpolation. The trade-off is direct—raising the TTL lowers bandwidth and join latency but risks serving stale actions, while lowering the TTL forces fresher data at the cost of higher network traffic and slower joins.
This decision is complicated by deployment and version differences. TTL expiry behaves differently on managed Photon Cloud versus a self-hosted on-premise server, and version 5.x introduced a revised cache invalidation algorithm that may alter the stale-data window compared to earlier releases. Because these factors change the effective freshness of the first snapshot, a single configuration may not be optimal across environments.
For a real-time session where new players must see recent actions without an unacceptable join delay, which approach should take priority when configuring LoadBalancingClient.LoadBalancingConfiguration?
35275 reputation · 25 Nov 2021, 21:02 UTC
For a real-time session where joining players must see recent actions without excessive join delay, prioritize client-side state interpolation over aggressive Room Cache TTL reduction. A moderate TTL (60–120 seconds on self-hosted) combined with interpolation handles the vast majority of joins. Only lower TTL further if your room churn exceeds ~20 joins/minute and bandwidth budget permits the 2–3× initial snapshot cost.
Interpolation (PhotonView.OnSerializeView smoothing + lag compensation) masks staleness up to ~200 ms by predicting and reconciling entity positions. This covers the typical delta between a cached snapshot and the live authoritative state. TTL reduction only helps when the cache is older than the interpolation window—i.e., when a room sits empty long enough for the snapshot to drift beyond what smoothing can hide.
On Photon Cloud you cannot tune Room Cache TTL per room; the managed backend uses an opaque ~300 s default. EmptyRoomTtl controls room persistence after the last player leaves, not cache freshness for joining players. Your only levers on Cloud are client-side: JoinMode.RejoinOnly with ExpectedUsers to force a fresh state fetch, and interpolation quality (serialization rate, PhotonView settings).
Photon Server SDK v5 introduced deterministic cache invalidation tied to actor list changes and event cache slices. This shrinks the stale-data window compared to v4's pure time-based expiry. On v5 self-hosted you can set RoomCacheExpirationInSeconds=0 in PhotonServer.config to disable caching entirely, forcing a fresh snapshot on every join—but this also disables event cache slices, breaking late-join RPC/ReplayEvent replay. A moderate TTL (60–120 s) preserves event replay while keeping snapshots fresh enough for interpolation to cover the gap.
On v4 or older self-hosted builds, the time-only expiry means a room empty for 5 minutes serves a 5-minute-old snapshot. Interpolation cannot recover missed authoritative events (physics triggers, score changes). If you run older builds and see join-time desyncs, lowering TTL is the only fix.
<RoomCacheExpirationInSeconds>60</RoomCacheExpirationInSeconds> in PhotonServer.config. Keep <EnqueueCacheSlices>true</EnqueueCacheSlices> for event replay.LoadBalancingClient.OpJoinRoom with JoinMode.RejoinOnly + ExpectedUsers when you need a guaranteed fresh fetch (e.g., after a known server-side state reset).NetworkTrafficStats.TimeToFirstSnapshotMs and compare PhotonView.lastOnSerializeTime vs server timestamp on join. If snapshot age >200 ms correlates with visible desync, lower TTL by 30 s increments.What is your typical room state size (custom properties + cached events in KB) and peak joins per minute? This determines whether the TTL=0 bandwidth penalty is acceptable or if 60 s TTL is already over-provisioned.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 25 Nov 2021, 22:45 UTC
On self-hosted Photon Server v5.x, cache eviction may be tied to actor-list changes and event-cache slices, not just the configured TTL. If so, a high-churn room can serve a snapshot older than expected even with a moderate TTL, while interpolation only smooths updates after the initial join frame. A conservative verification is to snapshot the first received state during a join storm and compare it against an idle room at the same TTL; divergence suggests event-driven invalidation is dominating the freshness window.