A multiplayer level has 100+ replicated actors — players, projectiles, pickups, and static decorations — with dozens of players connected. The dedicated server is CPU-bound on its networking loop: every tick it recomputes per-connection relevancy and diffs every actor's replicated properties, and bandwidth to each client is saturated. Most actors rarely change, and many are far from any given player. Describe how you would bring the per-tick networking cost down. Requirements: distant and irrelevant actors stop consuming send work for a given client; rarely-changing actors are not reconsidered every tick; only the properties a client actually needs are sent; and the approach must keep scaling as actor and player counts grow.
Cut per-tick work: tune NetUpdateFrequency and NetCullDistanceSquared, use dormancy for static actors, gate properties with DOREPLIFETIME_CONDITION, and adopt the Replication Graph for spatial culling at scale.
- ✗Marking everything
bAlwaysRelevant, which defeats relevancy culling - ✗Leaving
NetUpdateFrequencyhigh for actors that rarely change - ✗Never using dormancy for static or idle actors, so the server keeps processing them every tick
- →How would you profile to confirm replication is the actual bottleneck?
- →What trade-off does lowering
NetUpdateFrequencyintroduce for fast-moving actors?
Problem statement
A level with 100+ replicated actors and dozens of players. The server burns too much CPU on the net loop: every tick it computes relevancy per connection and diffs every actor's properties.
Solution components
1. Relevancy and distance culling
radius. The baseline defense against sending everything to everyone.
NetCullDistanceSquared— an actor stops replicating to clients outside the- Do not overuse
bAlwaysRelevant— it disables culling.
2. Update frequency
A static prop is fine at 1–2 Hz; a player pawn needs 30–60 Hz.
updates while an actor is unchanging.
NetUpdateFrequencysets how often an actor is considered for replication.MinNetUpdateFrequencytogether with adaptive net update frequency lowers
3. Dormancy
the net loop until FlushNetDormancy is called.
- Static or idle actors are set to
DORM_DormantAll. The server skips them in
4. Conditional property replication
for private data, COND_SkipOwner for owner-predicted state. Fewer properties means less diffing work.
DOREPLIFETIME_CONDITIONrestricts a property — for exampleCOND_OwnerOnly
5. Replication Graph
spatial nodes (grid spatialization), and per-connection lists are gathered from the nodes instead of a full scan.
- At scale this replaces the per-actor relevancy loop. Actors are placed into
Data flow
Server: state change
→ actor in Replication Graph node (or per-actor loop)
→ relevancy / distance / dormancy culling
→ property diff filtered by DOREPLIFETIME_CONDITION
→ packet to connection
Client: apply properties → OnRep callback
Trade-offs
causes desync.
to debug.
- A low
NetUpdateFrequencysaves CPU but adds jitter to fast actors. - Dormancy is free for static actors, but a forgotten
FlushNetDormancy - The Replication Graph scales best but needs node-setup code and is harder