The case against SQL
Based on Theo - t3․gg's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.
SQL is treated as the wrong abstraction for application code because it’s a textual, console-era interface rather than a typed function-like API.
Briefing
SQL’s biggest sin isn’t that it’s inherently unsafe—it’s that it’s the wrong abstraction for application code. The core claim driving the discussion is that developers shouldn’t build business logic by stitching together raw SQL strings; instead, application layers should call stable, typed operations (functions/methods) that hide database internals while still letting the database remain the system’s state and truth.
The argument starts with SQL’s origin: it was designed as a console/reporting language, not as a programming interface. Passing textual queries through application layers forces programmers to treat data access like string construction, even though the database engine ultimately compiles SQL into internal representations and executes it via function-like mechanisms. That mismatch leads to a proliferation of “layers” (ORMs, query builders, sanitization patterns) that often don’t provide the right developer experience—especially around type safety, schema evolution, and preventing subtle bugs.
A major thread is the security angle. The harshest version of the “anti-SQL” stance frames SQL injection as a structural failure: if user-controlled text can reach a SQL engine, unauthorized access becomes possible. The counterpoint offered here is that modern frameworks and parameterized query mechanisms largely mitigate SQL injection when raw SQL strings aren’t built unsafely. The broader security lesson shifts toward the reality that injection-like risks exist wherever untrusted input is rendered or executed—HTML/JS contexts (XSS) being an example—so focusing solely on SQL can become a crutch.
From there, the discussion pivots to what SQL does well and where it breaks down. SQL’s strengths include standardization across engines (SQLite, Postgres, MySQL, Cassandra), enabling tooling and portability, and allowing deep optimization between the SQL layer and the database engine. It also enables industry-wide innovation such as sharding and features like row-level security or real-time update pathways.
Where the critique sharpens is in application integration. Raw SQL in app code tends to produce weak typing (results often become any/unknown), disconnects schema changes from compile-time feedback, and encourages “stringly typed” data access. The response favors alternatives that keep SQL’s power but move the interface upward: typed query builders/ORM-like layers (the transcript calls out Drizzle as an example) and higher-level data access objects that expose explicit operations like “get by id” or “mutate update subscription,” with types inferred from schema definitions.
The strongest practical examples come from newer database/application architectures. The transcript praises systems like Gel (EdgeDB) for a more application-shaped query syntax, and Convex for treating application logic as a pipeline from database state to UI updates—reducing client/server out-of-sync problems by pushing updates through a transaction-aware abstraction. Even so, the speaker draws a line: the goal isn’t to eliminate database abstraction entirely, but to avoid writing raw SQL directly in application code and to reduce stateful, hard-to-debug service objects.
In the end, the shared conclusion is narrow but firm: SQL is the wrong abstraction to write directly in application code. The database should remain the source of truth, but the interface should be a typed, intention-revealing layer that turns data into experiences with fewer opportunities for brittle glue code and hidden failure modes.
Cornell Notes
SQL’s central problem in application development is abstraction mismatch: it was built for console-style querying, yet app code often treats it like a programmable interface by constructing textual queries. The discussion argues that raw SQL in application code invites weak typing, brittle schema coupling, and hard-to-debug layers, even if SQL injection is largely mitigated by modern parameterization. SQL still earns its keep as a standardized, optimizable query language for data engines and cross-database tooling. The preferred direction is a typed access layer—query builders, data objects, or higher-level database platforms—that exposes explicit operations and keeps schema changes aligned with compile-time feedback. The practical payoff is fewer security footguns, fewer out-of-sync client/server states, and easier debugging through clearer input/output boundaries.
Why does the transcript treat SQL as a “bad programming interface” even though databases execute SQL internally via compiled representations?
How does the security argument evolve from “SQL injection is structural” to “focus on the real risk surface”?
What are SQL’s strongest reasons for success, and why do they not fully rescue it as an app-layer interface?
What does “type safety” mean in this context, and why does raw SQL push results toward any/unknown?
Why does the transcript favor higher-level abstractions like Convex or Gel instead of “just call the database API directly”?
What is the “debuggability” argument against stateful service objects and for pipeline-style functions?
Review Questions
- What specific developer problems does the transcript associate with writing raw SQL directly in application code (typing, schema coupling, debugging, etc.)?
- How does the transcript reconcile SQL’s security history with the claim that SQL injection is mostly solved today?
- Compare the roles of SQL, an ORM/query builder, and a higher-level platform like Convex in the transcript’s ideal architecture. What changes and what stays the same?
Key Points
- 1
SQL is treated as the wrong abstraction for application code because it’s a textual, console-era interface rather than a typed function-like API.
- 2
Modern parameterization and safe templating reduce SQL injection risk, so “stop using SQL” is not the only (or best) security lesson.
- 3
SQL remains valuable inside databases for standardization and deep query optimization across engines.
- 4
Typed query builders and data-access objects (e.g., Drizzle-style schema-driven typing) connect database structure to application compile-time feedback.
- 5
Higher-level platforms like Convex aim to prevent client/server out-of-sync bugs by treating data updates as pipeline outputs with transaction-aware synchronization.
- 6
Debugging improves when application logic is structured as clear input/output pipelines rather than stateful service objects with hidden internal state.
- 7
The practical consensus is narrow: avoid writing raw SQL strings directly in application code, even if SQL stays central as the database’s query language.