OFPA is a source control feature, not a storage detail
One File Per Actor saves the data for each actor instance into its own external file rather than into the level. Epic's documentation states the purpose directly: because actors are saved to individual files, you do not need to check out the Level file from source control to change the actors inside it. That frees the Level file for everyone else on your team.
Read that again, because it is the whole point. OFPA was not built to make loading faster or to tidy up the content browser. It was built because the single biggest bottleneck in Unreal team development was that one person editing one thing in a level locked out everyone else. It is enabled by default when you use World Partition.
What actually changes in your project folder
Before OFPA, a level was one large .umap. After OFPA, the level file becomes small and the actor data moves into a directory tree beside it:
Content/
Maps/
OpenWorld.umap ← now small
__ExternalActors__/
Maps/
OpenWorld/
0/A2/BQ1FVJ8XZ2LK3M9N.uasset ← one actor
0/A2/C8DHW4RT6YU7IOP0.uasset ← one actor
... ← thousands more
__ExternalObjects__/
Maps/
OpenWorld/
...Every actor you place is now its own binary file with a hashed name. A moderately populated open world level produces thousands of them. Two artists dressing different districts of the same city now touch entirely separate files, which is exactly what Epic wanted.
The trade is that your repository's shape changed fundamentally. You went from a handful of enormous binaries to tens of thousands of small ones, and not every version control system copes with that equally well.
Why Git LFS struggles with OFPA
Git LFS replaces each binary file with a small text pointer and stores the real content elsewhere. That design is fine for a few hundred large assets. It behaves poorly when you hand it tens of thousands of small ones.
Each actor file needs its own pointer, so your Git index grows by an entry per actor. Common operations that walk the index, including git status, checkout, and branch switching, slow down noticeably. Every one of those tiny files is also a separate LFS object, which means a separate network round trip during fetch unless your client batches well. Teams often discover this at the worst moment: the repository was fine during greyboxing and became painful once the world got populated.
Keeping the actor files in regular Git instead of LFS is not a fix. They are binary, so every edit stores a complete new copy in history and the repository grows without bound.
Do you still need locking with OFPA?
Yes, and the reason is worth being precise about, because this is where teams get it wrong.
OFPA removed the level file bottleneck. It did not make individual assets mergeable. Every actor file is still a binary .uasset. Blueprints, materials, and meshes are all still binary. If two people open the same actor, or the same Blueprint, one person's work is still lost on save.
What changed is the probability. Before OFPA, collisions were near certain, because everyone shared one file. After OFPA, collisions are occasional and specific, which paradoxically makes them more dangerous: teams stop expecting them and stop communicating about them.
Per-file locking is what closes the remaining gap. Lock the specific actor or Blueprint you are editing, and teammates see it immediately. Everyone else in the level keeps working uninterrupted, which is the whole benefit OFPA was supposed to deliver.
Setting your team up
A few decisions make the difference between OFPA working well and OFPA quietly degrading over months.
Commit the whole external actors tree. Do not be tempted to exclude __ExternalActors__ because of the file count. That directory is your level now.
Decide about HLOD output. Generated HLOD data can be rebuilt, so some teams exclude it and rebuild locally. Others commit it so every machine and every build agent produces byte-identical results. Both are defensible. Pick one, write it down, and make sure everyone follows it, because a half-committed HLOD directory causes confusing diffs.
Keep the standard Unreal exclusions. Saved/, Intermediate/, DerivedDataCache/, and Binaries/ should never be versioned. USourceControl excludes these by default.
Agree on a locking convention. Lock before you open, not after you start editing. Release on commit. The habit matters more than the tooling.
How USourceControl handles it
Many small binaries is the normal case for us rather than an edge case, because Unreal Engine 5 is the only engine we support.
There is no pointer-file layer, so there is no index to bloat. Sync compares content hashes and moves only the files that actually changed, so a commit that touches forty actors uploads forty files rather than walking your whole world. A single commit can carry up to 25,000 files, which comfortably covers a full level rebuild. Locking is per file and server-authoritative, so two people editing different actors in the same World Partition level never block each other, and two people reaching for the same actor find out immediately rather than at merge time.
Storage and bandwidth are unlimited on every plan, including the free one, so the file count in your external actors directory is not something you need to budget for.
Frequently asked
Does One File Per Actor eliminate the need for file locking?
No. OFPA removes the level-file bottleneck, so people working on different actors no longer block each other. It does not make individual assets mergeable. Each actor file is still a binary .uasset, and Blueprints are still binary too. If two people open the same one, someone's work is still lost. Per-file locking is what closes that remaining gap.
Should I commit the __ExternalActors__ folder to source control?
Yes, always. After OFPA is enabled, that directory holds your actual level content. The .umap file becomes a small shell. Excluding __ExternalActors__ means committing an empty world.
Why does Git LFS get slow on a World Partition project?
OFPA produces tens of thousands of small binary files, and Git LFS creates a pointer for each one. The Git index grows by an entry per actor, so operations that walk the index (status, checkout, branch switching) slow down. Each tiny file is also a separate LFS object to transfer. LFS was designed for a few hundred large assets, not tens of thousands of small ones.
Should I version HLOD data?
Either choice works, as long as your team is consistent. Committing it guarantees byte-identical results across machines and build agents. Excluding it keeps the repository smaller and rebuilds locally. The failure mode is a half-committed HLOD directory, which produces confusing diffs, so decide once and document it.
Does OFPA work without World Partition?
Yes. You can enable One File Per Actor on a standard level from World Settings. It is enabled automatically with World Partition, but the two features are independent, and OFPA's source control benefits apply either way.
Can two people edit the same World Partition level at the same time?
Yes, and that is the point of OFPA. As long as they are working on different actors, their changes land in different files and never conflict. Locking handles the case where they reach for the same actor.