---
title: "ORM or Native SQL?"
description: "Is the ORM making us lazy, or actually protecting us? The balance of safety, readability, and performance between the two approaches"
url: https://sade.dev/en/journal/orm-vs-native-sql/
lang: en
author: "Muhammet Şafak"
published: 2026-09-12
section: Journal
tags: ["database","orm","sql","opinion"]
---

# ORM or Native SQL?

> Is the ORM making us lazy, or actually protecting us? The balance of safety, readability, and performance between the two approaches

A single page of an admin panel was firing 1,400 queries. The cause wasn't visible on screen: inside a loop, the innocent-looking `$order->customer->name` call fired a separate query for every order. The ORM hadn't actually hidden anything — it had only let the developer stop thinking about which query was running.

Is the ORM making us lazy, or protecting us? The answer is both — and the team decides which one dominates.

## What an ORM buys you

The ORM has real upsides, and they shouldn't be dismissed:

- **Safety.** Queries are parameterized by default; under ordinary use, the SQL injection surface is closed.
- **Readability.** For CRUD operations, `User::create($data)` is shorter and clearer than a hand-written `INSERT`.
- **Less repetition.** Relationships, migrations, model events — all in one place.

The vast majority of projects are CRUD at their core, and for that work the ORM is the right default. I have no objection to that.

## Where the ORM makes you lazy

The danger isn't in what the ORM does, but in what it **hides**. The ORM keeps SQL out of sight; and when the developer can't see the SQL, they stop thinking about which query is running.

The result is familiar: the N+1 from the opening of this piece; pulling a whole row into memory when a single column would do; forgetting a `where` and unknowingly loading an entire table. The ORM doesn't "do" any of these; they're all done by the developer who never looks at what the ORM produces.

In the [data-intensive systems](/en/systems/data-intensive-systems-breaking-points) piece, the first row of the false-breaking-points table is exactly this: what looks like "the database is slow" is, most of the time, the application firing 200 queries.

## Where the ORM ends

The ORM shines at transactional CRUD: create a record, update it, read it with its relationships. Where it struggles is just as clear:

- Multi-table, multi-step reports.
- Aggregations, window functions, complex conditions on top of `GROUP BY`.
- Bulk operations — a single `UPDATE` instead of walking millions of rows one model at a time.

For this kind of work, insisting on the ORM produces code that is both slower and less readable. Plain SQL is both faster and clearer here. Picking the right indexes is part of this work too — the [index management](/en/notes/index-management) note covers that side.

## The call: ORM as default, SQL as a tool

The two aren't rivals. The right use is roughly this:

- 90% of the work — CRUD, simple lists — with the ORM. Fast, safe, readable.
- The remaining 10% — heavy reporting, aggregation, bulk operations — with the query builder or plain SQL.

The mark of seniority isn't knowing the ORM; it's knowing **where it ends**. A team that forces the ORM onto everything turns it into a performance trap; a team that never uses the ORM and writes everything by hand gives up safety and readability for nothing.

## Both can be written safely

A common mistake: "plain SQL = unsafe." What provides safety isn't the ORM; it's **parameter binding**. A plain query written with bound parameters is as closed to injection as the ORM:

```php
DB::select('SELECT id, total FROM orders WHERE status = ?', ['pending']);
```

What's dangerous isn't plain SQL; it's embedding user input into the query through string concatenation — and you can do that inside the ORM's `whereRaw` too. The habit protects you, not the tool.

---

The ORM can be a laziness machine or a safety net — the difference is made by how the team looks at it. Use it, but never stop seeing what it produces.

A good developer writes with the ORM; they also know when to put it down.
