Skip to content

Back to blog

Architecture

DTO vs ORM: what's the difference?

· 7 min

"DTO vs ORM" is a common way to phrase the question, but a slightly misleading one, the two aren't alternatives to each other. One models how data moves; the other models how data is persisted.

Illustration of two connected hexagons

What an ORM actually does

An ORM (Object-Relational Mapper) maps database rows to language objects, tracks their state (dirty checking), and translates method calls into SQL. It lives at the persistence boundary, between the application code and the database.

What a DTO actually does

A DTO (Data Transfer Object) is a plain, serializable structure with no behavior, used to move a specific shape of data across a boundary, between the API layer and its clients, for instance, or between services. It exists to decouple what gets exposed externally from what's modeled internally.

Why exposing the ORM entity directly is a problem

Serializing an ORM entity straight into an API response is a common anti-pattern: it leaks internal columns that shouldn't be public, lazily-loaded relations can trigger unexpected extra queries during serialization, the classic N+1, and any change to the database schema silently changes the public API contract.

How the two work together

The typical flow: a request comes in and gets mapped to and validated as an input DTO; the service layer uses the ORM entity for business logic and persistence; before responding, the entity gets mapped back into an output DTO (possibly a different shape than the input). Each layer only knows the shape it actually needs.

When skipping the DTO is fine

For small internal tools or prototypes, where the API and the data model are genuinely the same shape and unlikely to diverge, skipping the DTO layer is a reasonable simplification. The mapping only pays for itself once the two actually need to evolve independently.