Database Access
ORM, query builder or raw SQL as an engineering decision with consequences, plus the query patterns and pool limits that decide how a backend behaves under load.
ORM, query builder, raw SQL and stored procedures as four points on a spectrum, chosen per query rather than per project.
Object method to generated SQL to database, plus the identity map, unit of work and lazy proxies that decide when statements are issued.
An honest ledger: real productivity on entity-shaped work, real opacity on query count, plans and complex reads.
One query for the list, one more for every row: 100 users become 101 statements, and the source code shows none of it.
The two general fixes for per-row queries — load the relation up front, or collect the ids and fetch once — and what each one over-fetches.
Composing SQL structurally in the host language: dynamic filters without string concatenation, and no mapping layer to explain.
When to write the statement yourself, how to keep it parameterized and findable, and what you take on when you do.
Schema change as a deployment problem: two code versions run at once, and some `ALTER TABLE` statements take a lock that stops the service.
The pool is what actually bounds your concurrency: 1,000 requests against 20 connections means 20 running and 980 waiting, silently, until they time out.