Choosing Photon Interest Groups to Reduce Unnecessary Network Traffic
Learn when to enable Photon Interest Groups, how they compare to other filtering methods, and see a concrete Unity-PUN 2 implementation with verification steps.
01 Jun 2026, 21:19 UTC

Problem: Unwanted event traffic wastes bandwidth
In a multiplayer room, each client may raise events that are only relevant to a subset of players (e.g., voice chat for nearby avatars, score updates for a specific team). By default, Photon broadcasts every event to all clients in the room, which can cause unnecessary bandwidth usage and increase latency, especially in large-scale games.
Decision: Use Interest Groups or an alternative?
You must decide how to limit event reception. The main options are:
| Option | How it works | Pros | Cons |
|---|---|---|---|
| Interest Groups (built-in) | Clients subscribe to byte-coded groups (0-255). Events are sent with a target group; only clients subscribed to that group receive it. | Zero server-side changes, works with UDP/TCP, reduces traffic at the network layer. | Requires client-side bookkeeping, limited to 256 groups, frequent changes add CPU overhead. |
| Client-side filtering | All clients receive every event; each client discards unwanted events based on custom data. | Simple to implement, no group limit. | Wastes bandwidth because unwanted events still travel over the network. |
| Separate rooms per interest | Create a distinct room for each group of players (e.g., team rooms). | No extra client logic, perfect isolation. | Increases room management complexity, players cannot interact across rooms without extra messaging. |
| Custom properties + polling | Store relevance data in room properties; clients read properties to decide whether to act. | Leverages existing Photon property system. | Properties are limited in size and frequency; not suited for high-frequency events. |
Trade-offs of Interest Groups
Interest Groups shift filtering to the transport layer, which saves bandwidth but adds a few considerations:
- Group limit: Only 256 distinct groups exist. For games with many dynamic relevance criteria (e.g., thousands of proximity-based zones), you must map multiple criteria onto the same group or use a hierarchy.
- Subscription overhead: Changing groups involves a round-trip to the server. Doing this every frame can hurt CPU and network performance; best practice is to set groups when a player enters a room or when their relevance changes significantly.
- Compatibility: Works with both UDP and TCP transports and with Photon Cloud or self-hosted Photon Server, so no server-side upgrade is needed.
If your game needs more than 256 logical groups or you want zero client bookkeeping, consider the separate-room approach. Otherwise, Interest Groups provide the best bandwidth-to-complexity ratio.
Concrete implementation (Unity PUN 2)
The following C# snippet shows how to enable a specific interest group, send an event to that group, and reset to the default state. Place this script on a GameObject in your scene.
using Photon.Pun;
using Photon.Realtime;
using System;
using UnityEngine;
public class InterestGroupDemo : MonoBehaviourPunCallbacks
{
// Choose a group ID within 0-255
private const byte TargetGroup = 1;
private void Start()
{
// Ensure we are in a room before configuring groups
if (PhotonNetwork.InRoom)
{
EnableInterestGroup(TargetGroup);
}
}
public override void OnJoinedRoom()
{
base.OnJoinedRoom();
EnableInterestGroup(TargetGroup);
}
private void EnableInterestGroup(byte group)
{
// Enable the desired group; disable all others for clarity
byte[] groupsToEnable = new byte[] { group };
byte[] groupsToDisable = new byte[0]; // empty disables none
PhotonNetwork.SetInterestGroups(groupsToDisable, groupsToEnable);
Debug.Log($"Interest group {group} enabled.");
}
///
/// Sends a custom event only to clients subscribed to TargetGroup.
///
public void SendGroupEvent(byte eventCode, object customData)
{
// The RaiseEventOptions lets us specify the target interest group
var options = new RaiseEventOptions { TargetInterestGroups = new byte[] { TargetGroup } };
// Use Reliable if ordering matters; Unreliable for fire-and-forget
PhotonNetwork.RaiseEvent(eventCode, customData, options, SendOptions.SendUnreliable);
}
///
/// Optional: reset interest groups to default (group 0) when leaving the room.
///
public override void OnLeftRoom()
{
base.OnLeftRoom();
// Disable all custom groups; leaves only the default group 0 enabled
PhotonNetwork.SetInterestGroups(new byte[0], new byte[] { 0 });
Debug.Log("Interest groups reset to default.");
}
}
Where to run: Attach the script to any active GameObject in a Unity scene that uses PUN 2. The script requires no special permissions beyond those needed for the Photon connection.
Expected checks: After calling SendGroupEvent, only clients that have enabled TargetGroup will invoke OnEvent (or a custom callback) with the supplied eventCode and customData. Clients with different groups or no group enabled should not receive the event.
Risks: If you pass a group ID outside 0-255, the SDK will ignore the call or throw an ArgumentException. Frequent calls to SetInterestGroups (e.g., every Update) increase CPU usage and can cause temporary throttling by the Photon server.
Validation steps (no output invented)
- Create two Unity builds (or two editor instances) named ClientA and ClientB.
- Have both clients connect to the same Photon room using the same AppId and region.
- In ClientA's script, call
EnableInterestGroup(1); in ClientB's script, callEnableInterestGroup(2). - From ClientA, invoke
SendGroupEvent(200, "Hello Group 1"). - Observe the logs:
- ClientA should see its own event (if you also listen for events on the sending client).
- ClientB should not log receipt of the event.
- Add a third client, ClientC, that enables group 1; it should log receipt of the event.
- Repeat the test with the Photon transport set to TCP (
PhotonNetwork.UseTcp = true;) to confirm that the filtering works independently of the underlying protocol.
If the event appears only on the expected clients, the Interest Group configuration is functioning correctly. If you see unexpected receptions, double-check that group IDs are within the allowed range and that you are not accidentally enabling the default group 0 on all clients.
Limitations and practical checks
Interest Groups do not encrypt event content; they only limit who receives the payload. For sensitive data, still consider encryption or authentication layers. Additionally, the 256-group ceiling means you must design a grouping strategy—for example, assign groups to static zones (e.g., map sectors) and reuse groups for dynamic entities via bit-masking or time-based rotation.
A quick way to verify that you have not exceeded the limit is to log the length of the arrays passed to SetInterestGroups and ensure each element is between 0 and 255. Photon's client logs also warn when an invalid group ID is supplied.
Rollback considerations
Changing interest groups modifies the client's subscription state. To revert to the default configuration (only group 0 enabled), call:
PhotonNetwork.SetInterestGroups(new byte[0], new byte[] { 0 });
This operation is safe to run at any time, such as when a player leaves the room or when you disable the feature entirely.
Takeaway
If your goal is to cut unnecessary network traffic while keeping server-side changes to zero, Photon Interest Groups are the most efficient built-in solution—provided you stay within the 256-group bound and manage subscription changes prudently. Use the table above to weigh this against client-side filtering or separate rooms, and follow the Unity example to implement and verify the feature in your own project.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.