GameObjects vs ECS: How Unity's DOTS Works
A plain-language look at how Unity's ECS and DOTS compare to classic GameObjects, and when the switch is actually worth it.
Have you ever played a game with thousands of moving units on screen at once? Maybe it was a huge battle, a zombie horde, or a busy city full of people. Have you ever wondered how it all stays smooth? Meanwhile, other games slow down with just a few hundred objects on screen.
The difference is often not about the graphics card. It is about how the game stores its data, and how it processes that data every frame. This post looks at two different ways to build a game in Unity: the classic GameObject approach, and a newer approach called ECS (Entity Component System), which is part of Unity's DOTS (Data-Oriented Technology Stack).
The Classic Way: GameObjects
If you have used Unity before, you already know GameObjects. A GameObject is like a container. You create, or "instantiate," one for each thing in your game — a soldier, a car, a tree — and you attach pieces called components to it: a Transform component for its position, maybe a Health component, a script that controls movement, and so on. All these pieces live together, inside one object.
This way of thinking feels natural. A soldier "has" a position. A soldier "has" health. A soldier "has" a target. This matches how we describe things in everyday language, so it is easy to learn. It is also why almost every Unity tutorial teaches this method first.
But behind the scenes, each GameObject is stored as its own separate block in memory. If your game has 500 soldiers, you have 500 separate blocks, scattered across memory, each one holding its own private copy of position, health, and other data.
Where This Approach Runs Into Trouble
At small numbers, none of this is a problem. A few hundred GameObjects run fine on almost any computer. But once a game needs thousands, or tens of thousands, of active objects, like a horde of Zombies, little soldiers in an RTS game, this classic method starts to slow down. There are two main reasons.
First, memory is scattered. A computer's processor, or CPU, is very fast at reading data that sits close together in memory. It is much slower when it has to jump from place to place. Each GameObject keeps its own data in its own block. Because of this, the health values of 500 soldiers are not stored next to each other — they are spread out, mixed in with everything else. Every time the game checks the health of each soldier, the CPU has to jump around to find each value, and this wastes time.
Second, work is hard to split up. Modern CPUs have several cores, so they can work on more than one task at the same time. But GameObjects are not built for this. Their data is too scattered and too tangled to safely divide between cores. So Unity mostly processes GameObjects one at a time, on a single core, even while the other cores sit unused.
A Different Idea: Data-Oriented Design and ECS
ECS solves both problems by starting from a different question. Instead of asking "what is this thing, and what does it have?", it asks "what kind of data do I have, and what do I need to do with each kind?"
Rather than storing one soldier's position, health, and target together in a single bundle, ECS stores all positions together, in one long list. It keeps a separate list for all health values, another for all targets, and so on. Data of the same kind sits together, in order, instead of being grouped by object.
ECS is built from three simple parts:
- Entity – just an ID number, similar to a name tag. It holds no data itself. It only marks which pieces of data belong to the same "thing."
- Component – pure data, and nothing more. A Position component only holds numbers, such as x, y, and z. A Health component only holds a number. There is no behaviour inside a component, only values.
- System – this is where the logic lives. A System is a piece of code that runs across every entity that has a certain set of components. For example, a "MovementSystem" would update the position of every entity that has both a Position and a Velocity component, all in one pass.
In short, Components hold data, Systems hold logic, and Entities tie the two together. This is quite different from a GameObject, which bundles data and behaviour into a single object.
Here is a simple picture of the difference:
GameObject approach — each unit is its own bundle:
[Unit A: position, health, target]
[Unit B: position, health, target]
[Unit C: position, health, target]
ECS approach — each kind of data has its own list:
Positions: [A's position, B's position, C's position]
Health: [A's health, B's health, C's health]
Targets: [A's target, B's target, C's target]
Putting It All Together: What DOTS Adds
Storing data this way solves the two problems above, but it needs help from two more tools to reach its full speed. Together, these three tools make up what Unity calls DOTS:
- Because all positions now sit together in one clean list, the CPU can read through them quickly, without jumping around. This fixes the memory problem.
- Because that same list can easily be split into equal pieces, Unity's Job System can give different pieces to different CPU cores, so they all work at the same time. This fixes the parallel work problem.
- The Burst Compiler then turns this code into a fast, low-level version, built specifically for the exact hardware it runs on, adding even more speed on top.
As a bonus, this organised structure also tends to behave more predictably between runs, which is useful for things like multiplayer games, where every player's computer needs to reach the same result. By 2026, this technology has matured enough that Unity is folding it more directly into the core engine, rather than keeping it as a separate, experimental add-on.
Put together, ECS gives you organised data, the Job System spreads the work across many cores, and Burst makes each piece of work run as fast as possible. This is why ECS-based games can handle tens of thousands of active objects at once — something that is very hard to do with plain GameObjects.
The Costs: Why ECS Isn't Always the Right Choice
ECS is powerful, but it is not a free upgrade. It comes with real costs, so it is not automatically the right choice for every project.
- It is a different way of thinking. Instead of one class holding both data and behaviour, you keep data (Components) and logic (Systems) separate. This takes practice, especially if you are used to standard object-oriented programming.
- It adds extra setup. For a small game with a few hundred objects, plain GameObjects are usually simpler, faster to build, and perform perfectly well. ECS can feel like extra work for little real benefit at that scale.
- You do not have to use it everywhere. Unity supports a mixed approach: keep normal GameObjects for things like menus, UI, or a small number of unique characters, and use ECS only for the parts of the game that truly need large numbers, such as thousands of units or particles.
- It is still evolving. Unity's ECS tools have changed quite a lot over the years and continue to improve. Because of this, it is worth checking official documentation for the latest guidance before starting a new project.
GameObjects vs ECS: A Quick Comparison
| GameObjects | ECS / DOTS | |
|---|---|---|
| Best for | Small to medium object counts (up to roughly a thousand) | Very large object counts (thousands and above) |
| Data storage | Bundled per object, scattered in memory | Grouped by data type, stored together |
| Multi-core use | Mostly one core at a time | Built to split work across many cores |
| Learning curve | Easy, matches familiar programming habits | Steeper, needs a new way of thinking |
| Good examples | UI, menus, a small number of unique characters | Bullets, particles, crowds, zombie hordes, large simulations |
Many real games use both at the same time. Complex, one-off objects, like the player's main character or the UI, often stay as GameObjects, since there are not many of them and each one needs its own unique behaviour. Meanwhile, large groups of similar, repeated objects, such as enemy waves or an army of units, move to ECS, where their large numbers can be handled well.
Choosing the Right Tool
GameObjects and ECS are not really rivals. They are two different tools, built for two different problems. GameObjects match the way people naturally think about the world, and for most games, that is more than good enough. ECS trades away some of that simplicity for raw processing power — power that only becomes necessary once a game's scale grows far beyond what the classic method can comfortably handle.
If your project stays in the hundreds of objects, you may never need ECS at all. But if you are aiming for thousands of moving parts on screen at once, learning ECS and DOTS is the first real step toward getting there.
Further reading: Unity's official DOTS overview at unity.com/dots