Executive Thesis
The mainstream story says modern products eventually outgrow relational databases. At some point, the story goes, a serious engineering organization must move beyond SQL into NoSQL because scale, speed, flexible schemas, and distributed systems demand it. That belief sounds sophisticated because it borrows language from companies that actually operate at massive scale. But for most teams, it is backwards.
Most teams do not need NoSQL. They need clearer data ownership, simpler domain modeling, better indexing, disciplined migrations, and a relational database used competently. NoSQL can be the right tool when the access pattern is known, the consistency tradeoff is intentional, and the operational model is understood. But when teams choose NoSQL because they want to “move fast,” “avoid schema,” or “prepare for scale,” they often buy the hard parts of distributed systems before they have earned the benefits.
The hidden cost is not only technical. It is managerial. NoSQL can turn data modeling from a shared institutional discipline into a collection of application-level conventions that only the original team remembers. It can move invariants out of the database and into code paths, services, queues, and tribal knowledge. It can make simple reporting, ad hoc debugging, compliance questions, and cross-entity workflows harder than they need to be. The result is not modern architecture. It is a pile of implicit contracts pretending to be flexibility.
The Serious CTO position is not “never use NoSQL.” That would be as lazy as “always use NoSQL.” The more useful rule is this: default to relational systems until a specific, measured, business-critical access pattern proves that a specialized database is worth the operational tax. PostgreSQL, MySQL, SQLite, and distributed SQL systems already cover more product needs than many teams admit. NoSQL should be a deliberate exception, not a status symbol.
The Narrative Conflict: Mainstream Belief vs. Engineering Reality
The mainstream belief has three parts. First, SQL is treated as old infrastructure: reliable, familiar, but somehow less suited to modern products. Second, schema is treated as friction: something that slows down product iteration because engineers must define structure before storing data. Third, NoSQL is treated as scale insurance: a way to avoid future pain by choosing a database that appears to be designed for growth from day one.
This story became plausible because the companies associated with NoSQL were solving real problems. Amazon Dynamo was built for highly available key-value workloads where service-level agreements demanded that failures be treated as normal operating conditions rather than exceptional events. The Dynamo paper describes a system designed for incremental scalability, high availability, and eventual consistency under Amazon’s demanding shopping-cart and service workloads. That is a legitimate engineering context. But it is not the context of most SaaS products trying to ship a customer dashboard, billing workflow, audit trail, analytics feature, or internal operations portal. [10]
DynamoDB’s own design guidance makes this point indirectly. Amazon’s NoSQL design documentation emphasizes that DynamoDB modeling begins with access patterns: understand the application’s queries first, then design tables and keys around those queries. In relational modeling, teams often begin by modeling entities and relationships, then query the data flexibly. In DynamoDB-style modeling, the database rewards teams that already know how the application will read and write data. That is powerful when the workload is known. It is dangerous when the product is still discovering what the data means. [5]
This is where the mainstream belief collapses. Early-stage and mid-stage products rarely suffer because the relational model is too rigid. They suffer because the business model is changing, reporting needs evolve, workflows get more complex, and teams discover relationships they did not understand at the beginning. Those are the conditions where relational systems are often strongest. Tables, constraints, joins, transactions, indexes, and migrations are not bureaucratic artifacts. They are the boring machinery that lets a team change its mind while preserving shared truth.
NoSQL does not remove schema. It relocates schema. Martin Fowler’s discussion of schemaless data structures makes the subtle point that “schemaless” rarely means there is no structure. It usually means the structure is implicit, enforced by application code, understood by conventions, or scattered across consumers. That can be useful when records genuinely vary and the team can tolerate local interpretation. It becomes painful when many services, reports, integrations, and human operators need a consistent understanding of the same data. [20]
The reality is that every serious system has a schema. The only question is whether the schema is explicit, reviewed, migrated, constrained, and visible—or implicit, duplicated, and discovered during incidents.
Quantitative and Market Evidence: SQL Did Not Lose
The death of SQL has been predicted for decades, yet relational systems remain dominant. DB-Engines continues to rank relational databases such as Oracle, MySQL, Microsoft SQL Server, PostgreSQL, and SQLite among the most widely used database systems. The exact positions shift, but the broad pattern is stable: relational systems are not legacy leftovers. They remain the default infrastructure of a huge portion of production software. [15]
Developer behavior tells a similar story. Stack Overflow’s 2024 Developer Survey lists PostgreSQL, MySQL, SQLite, and Microsoft SQL Server among commonly used database technologies. MongoDB and Redis also appear prominently, which matters: the modern reality is not SQL versus NoSQL as a religious war. It is a mixed ecosystem. But the continued strength of relational databases undermines the claim that serious modern engineering has moved beyond SQL. [16]
The tooling ecosystem also reinforces SQL’s staying power. ORMs exist because most applications still need to map domain objects to relational persistence. Prisma’s Data Guide describes ORMs as a bridge that lets developers work with application objects while relying on relational databases for persistence. ORMs have their own problems, but their existence reflects a durable fact: most business applications still depend on relational persistence because relationships, constraints, and transactions remain central to product behavior. [14]
PostgreSQL also weakens the simplistic argument that relational databases cannot handle flexible data. PostgreSQL supports JSON and JSONB types, validates JSON values, and provides JSON-specific operators and indexing options. That does not mean every document workload belongs in PostgreSQL. It means many teams reach for a document database because they want flexible fields when their existing relational database already provides a controlled version of that flexibility. [1]
SQLite makes another important point: database choice should match the deployment and workload, not fashion. SQLite’s own guidance says it is not directly comparable to client/server engines because it solves a different problem. That is exactly the mindset teams need. The question is not “which database is modern?” The question is “what problem are we actually solving?” [17]
The evidence does not say NoSQL is fake. It says SQL never stopped being useful, and many claims about outgrowing SQL are really claims about poor relational design, weak indexing, bad migrations, underpowered infrastructure, or leadership impatience.
The Real Tradeoff: NoSQL Optimizes Specific Access Patterns by Making Other Things Harder
The most important distinction is not SQL versus NoSQL. It is general-purpose modeling versus access-pattern-specific modeling.
Relational databases are strong when the data has relationships, invariants, transactions, and unpredictable query needs. They let teams express constraints, join across entities, inspect the system with ad hoc queries, and evolve data through migrations. PostgreSQL’s documentation on constraints shows how the database can enforce assumptions such as not-null requirements, uniqueness, primary keys, foreign keys, and check constraints. Those are not just storage details. They are production guardrails. [18]
PostgreSQL’s transaction isolation documentation shows another guardrail: a relational database can provide defined isolation behavior so concurrent work does not silently corrupt shared state. Teams still need to understand isolation levels, but the database gives them a language for reasoning about correctness under concurrency. [2]
NoSQL systems often trade some of that generality for speed, availability, distribution, or data-shape flexibility. DynamoDB asks teams to design around access patterns. Cassandra’s architecture inherits ideas from Dynamo and Bigtable, emphasizing distribution, replication, and high availability. Redis offers specialized in-memory data structures that are excellent for caching, queues, counters, locks, rate limits, leaderboards, and ephemeral coordination patterns. These are valuable tools. But they are valuable because they are specialized. [5][7][8]
The danger is when specialization is chosen before the team knows what should be specialized.
A relational schema forces a conversation: what is a customer, what is an account, what owns a subscription, what does “active” mean, what must be unique, what cannot be null, what changes together? NoSQL can postpone those conversations. But postponed modeling is not eliminated modeling. It returns later as migration pain, reporting hacks, duplicated validation logic, and production questions that nobody can answer with one query.
A document database may make early writes easier because the application can store nested structures without normalizing everything. MongoDB’s data modeling documentation highlights flexible schema design and the ability to embed related data. That can reduce joins and fit naturally with certain object graphs. But MongoDB’s own transaction documentation also exists because real applications eventually need atomicity across multiple documents, collections, or databases. Once those needs appear, the team is back in the world of transactions and consistency. [3][4]
The core lesson: NoSQL does not exempt a team from data modeling. It changes when and where the modeling bill arrives.
The Consistency Trap: Distributed Systems Are Not Free Scale
Many teams choose NoSQL because they associate it with scale. The mistake is treating scale as a database feature rather than an operational context.
The CAP theorem is often abused in engineering debates, but Eric Brewer’s later explanation is useful because it moves the discussion away from simplistic slogans. Distributed system designers must explicitly handle partitions and reason about the balance between consistency and availability. The point is not that one database is “CAP” and another is not. The point is that distribution forces tradeoffs that must be understood. [9]
DynamoDB exposes this directly through its read consistency options. It supports eventually consistent reads and strongly consistent reads with different semantics and constraints. That is not a flaw. It is a design choice. But it means the application and its engineers must understand when stale reads are acceptable and when they are not. [6]
Amazon Dynamo’s original paper describes eventual consistency as part of a system optimized for availability. Again, this is not wrong. It is appropriate for certain workloads. But if a product team is building billing, permissions, entitlements, financial records, audit logs, compliance workflows, or cross-entity business operations, “eventually consistent unless carefully designed otherwise” can become an expensive default. [10]
Google Spanner represents another branch of the story. It is a globally distributed database that provides externally consistent distributed transactions using sophisticated infrastructure and clock synchronization. Spanner is evidence that teams want both distribution and relational-style correctness. It is also evidence that providing both is complex enough to require serious systems engineering. [11]
This is the strategic point for CTOs: if your team does not currently have a measured scale problem, do not buy a distributed-systems problem because you imagine one day you might. You can scale a relational system surprisingly far with indexing, caching, read replicas, partitioning, query tuning, connection pooling, and sensible product constraints. When those stop being enough, the team will have better evidence about which part of the system needs a specialized store.
Premature NoSQL is not future-proofing. It is often future complexity purchased with present uncertainty.
The Reporting and Debugging Tax
One of the least glamorous reasons SQL wins is that humans need to ask questions.
A product manager wants to know how many accounts converted after using a feature. Finance wants to reconcile subscriptions. Support wants to inspect a customer state. Security wants an audit trail. Leadership wants cohort analysis. An engineer on call wants to know why a user can access something they should not. These questions are rarely known perfectly at design time.
Relational databases are built for this kind of interrogation. Joins, constraints, normalized structures, and ad hoc SQL let technical operators inspect reality. The database is not only a persistence layer. It is an operational truth surface.
NoSQL systems can support analytics and investigation, but often through additional systems: streams, ETL jobs, search indexes, warehouses, materialized views, secondary indexes, or duplicated read models. That architecture may be necessary at scale. But for many teams, it is self-inflicted complexity. They choose a database that makes the write path feel flexible, then spend months recreating the query flexibility they gave up.
This is especially dangerous for engineering leaders because the cost appears outside the original project estimate. The team ships the feature quickly. The tax arrives later when debugging needs cross-entity visibility, when a customer asks for an export, when compliance needs retention rules, when a metric must reconcile with revenue, or when an incident requires reconstructing state across services.
This is the operational version of technical debt: the system was easy to write into and hard to reason about.
The Hidden Leadership Failure
The “You don’t need NoSQL” argument is not really about databases. It is about leadership maturity.
Weak engineering organizations often confuse technology choice with architectural progress. A team adopts a document database and calls it modern. It adopts a key-value store and calls it scale. It adopts event-driven persistence and calls it decoupling. But the real test is not whether the database is modern. The real test is whether the organization can explain its invariants.
What must always be true? What can be temporarily inconsistent? What data belongs together? What can be duplicated? What is the source of truth? What queries must be fast? What queries must be possible? What failures are acceptable? What recovery process exists when the database does exactly what it was designed to do but the product assumed something else?
Relational databases force some of these questions into the open. NoSQL can let leaders avoid them by calling ambiguity “flexibility.” That is the leadership failure: mistaking postponed decisions for agility.
The better framing is this: schema is not the enemy of speed. Unexamined schema is. A relational schema can be too rigid, over-normalized, prematurely abstracted, or painfully bureaucratic. But an explicit schema is also a communication tool. It turns product assumptions into artifacts that can be reviewed, tested, migrated, and challenged.
NoSQL is most dangerous when it is used to avoid difficult conversations about the domain.
The Steel-Man Case for NoSQL
The argument needs a fair opposing side. There are real cases where NoSQL is the correct answer.
If the workload is naturally key-value, a relational database may be unnecessary overhead. Session stores, cache entries, feature flags, idempotency keys, rate-limit counters, and ephemeral coordination often fit specialized stores. Redis is a strong example of a system designed around data structures and low-latency operations rather than general relational modeling. [7]
If the workload is high-scale, high-throughput, and access-pattern-specific, DynamoDB can be excellent. It is managed, highly available, and capable of enormous scale when the table and key design match the access patterns. But that “when” matters. DynamoDB’s own guidance makes access-pattern design central, which means it rewards teams that understand their workload deeply. [5]
If the data is naturally document-oriented and most operations retrieve whole aggregates, a document database can be a strong fit. MongoDB’s embedding model can make sense when related data is usually accessed together and does not need heavy cross-document transactional behavior. [4]
If availability across distributed nodes is more important than immediate consistency for a given use case, Cassandra-style architectures can be appropriate. Systems that must remain writable across regions or survive partitions may reasonably choose tradeoffs that a traditional single-primary relational setup does not offer. [8]
If an organization has multiple persistence needs, polyglot persistence can be healthy. A relational source of truth can coexist with Redis for cache, Elasticsearch or OpenSearch for search, object storage for blobs, a warehouse for analytics, and a document store for a specific aggregate. The problem is not using NoSQL. The problem is using it as the default source of truth before the team understands the truth.
The strongest pro-NoSQL argument is not “SQL is old.” It is “this specific workload has a shape, scale, latency requirement, availability requirement, or data model that a specialized database serves better.” That is a serious argument. Anything less is fashion.
The Practical Control Framework
A CTO does not need a database religion. A CTO needs a decision framework.
First, default to boring truth. If the product has customers, accounts, permissions, subscriptions, invoices, workflows, approvals, audit trails, or reporting needs, begin with a relational database unless there is a concrete reason not to. PostgreSQL is a strong default because it provides relational modeling, transactions, constraints, indexing, full-text capabilities, JSON support, and a mature ecosystem. MySQL and SQLite also have strong use cases depending on deployment and team constraints. [1][2][17][18]
Second, define invariants before choosing the database. If the answer includes “this must never happen,” that is a signal to prefer systems that make constraints and transactions easy to reason about. If the answer includes “this can be stale for a few seconds and corrected later,” a different set of tools becomes possible.
Third, separate system-of-record storage from derived views. It is often sensible to keep canonical data in a relational database while projecting specialized read models into Redis, Elasticsearch, a document store, or a warehouse. This gives the business a source of truth while still serving performance or search needs.
Fourth, require an access-pattern document before adopting NoSQL. For DynamoDB especially, the team should list the reads and writes the application must support, their expected volumes, latency needs, consistency requirements, and failure behavior. If the team cannot produce this document, it is not ready for access-pattern-first persistence.
Fifth, price the operational tax. Who will operate the database? How will migrations work? How will data be repaired? How will support inspect state? How will analytics query it? How will backups and restores work? How will permissions and audit trails be enforced? What happens when the original developers leave?
Sixth, make reversibility explicit. A specialized store should have an exit plan or at least a boundary. If a NoSQL store becomes the canonical source of truth for a core domain without clear ownership and repair paths, the organization has accepted lock-in whether or not it admits it.
Seventh, do not punish the team for using boring tools. Leaders often create incentives for novelty and then complain about complexity. The correct leadership behavior is to reward durable simplicity: the design that future engineers can understand, query, migrate, and recover at 2 a.m.
Strategic Path Forward
The next decade will not be SQL versus NoSQL. It will be disciplined data ownership versus accidental data sprawl.
AI will make this more important, not less. AI-assisted coding can generate persistence layers quickly. It can create schemas, collections, repositories, migrations, and wrappers at high speed. That increases the risk of teams producing database architecture faster than they can understand it. The limiting factor is no longer how quickly engineers can write persistence code. The limiting factor is whether the organization can reason about correctness, ownership, and change.
The strategic path is to treat database choice as an organizational design decision. A database shapes what teams can inspect, what they can enforce, what they can change, and what they can safely ignore. SQL remains powerful because businesses are made of relationships, rules, histories, and exceptions. NoSQL remains powerful because some workloads are specialized, distributed, and access-pattern-driven. The mature organization knows the difference.
For the video angle, the sharp line is simple: you probably do not need NoSQL. You need to stop using hypothetical scale as an excuse to avoid present-day data discipline. Choose the boring relational database until the evidence says otherwise. When the evidence does say otherwise, use NoSQL deliberately, narrowly, and with full awareness of the operational tax.
The database that makes version one easy can make year three miserable. The database that looks boring on day one may be the reason the team can still understand the business on day one thousand.
Works Cited
1. PostgreSQL Documentation, “8.14. JSON Types,” accessed May 2026, https://www.postgresql.org/docs/current/datatype-json.html
2. PostgreSQL Documentation, “13.2. Transaction Isolation,” accessed May 2026, https://www.postgresql.org/docs/current/transaction-iso.html
3. MongoDB Documentation, “Transactions,” accessed May 2026, https://www.mongodb.com/docs/manual/core/transactions/
4. MongoDB Documentation, “Data Modeling in MongoDB,” accessed May 2026, https://www.mongodb.com/docs/manual/data-modeling/
5. Amazon DynamoDB Developer Guide, “NoSQL design for DynamoDB,” accessed May 2026, https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-general-nosql-design.html
6. Amazon DynamoDB Developer Guide, “DynamoDB read consistency,” accessed May 2026, https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadConsistency.html
7. Redis Documentation, “Redis data types,” accessed May 2026, https://redis.io/docs/latest/develop/data-types/
8. Apache Cassandra Documentation, “Dynamo,” accessed May 2026, https://cassandra.apache.org/doc/latest/cassandra/architecture/dynamo.html
9. Eric Brewer, “CAP Twelve Years Later: How the ‘Rules’ Have Changed,” InfoQ, accessed May 2026, https://www.infoq.com/articles/cap-twelve-years-later-how-the-rules-have-changed/
10. Giuseppe DeCandia et al., “Dynamo: Amazon’s Highly Available Key-value Store,” SOSP 2007, https://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf
11. James C. Corbett et al., “Spanner: Google’s Globally-Distributed Database,” OSDI 2012, https://static.googleusercontent.com/media/research.google.com/en//archive/spanner-osdi2012.pdf
12. Martin Kleppmann, “Using logs to build a solid data infrastructure (or: why dual writes are a bad idea),” accessed May 2026, https://martin.kleppmann.com/2015/05/27/logs-for-data-infrastructure.html
13. Prisma Data Guide, “What is an ORM (Object Relational Mapper)?”, accessed May 2026, https://www.prisma.io/dataguide/types/relational/what-is-an-orm
14. DB-Engines, “DB-Engines Ranking,” accessed May 2026, https://db-engines.com/en/ranking
15. Stack Overflow Developer Survey 2024, “Technology: Database,” accessed May 2026, https://survey.stackoverflow.co/2024/technology#most-popular-technologies-database
16. SQLite Documentation, “Appropriate Uses For SQLite,” accessed May 2026, https://www.sqlite.org/whentouse.html
17. PostgreSQL Documentation, “5.5. Constraints,” accessed May 2026, https://www.postgresql.org/docs/current/ddl-constraints.html
18. Jepsen, “MongoDB stale reads,” accessed May 2026, https://aphyr.com/posts/322-call-me-maybe-mongodb-stale-reads
19. Martin Fowler, “Schemaless Data Structures,” accessed May 2026, https://martinfowler.com/articles/schemaless/
Comments
Post a Comment