SQL vs NoSQL: A Pragmatic Guide
The relational vs document vs key-value debate, demystified. When to reach for each, how to migrate, and why 'SQL is old' is not an argument.
The “SQL vs NoSQL” debate peaked a decade ago and never really ended — it just stopped being interesting. Every engineering team eventually sits down and has this conversation, and most of them make the decision based on vibes and blog posts from 2014. This article is the pragmatic version: what each model is actually good at, and a decision process that starts with your data’s shape, not with a favorite tool.
What the names actually mean
“SQL” and “NoSQL” are bad categories. A better distinction is relational vs non-relational, and within non-relational, the shapes matter more than the label:
- Relational (PostgreSQL, MySQL, SQLite): rows, tables, schemas, joins, transactions
- Document (MongoDB, CouchDB): JSON-ish documents, flexible shape, embedded data
- Key-value (Redis, DynamoDB): simple lookups by key, massive scale, low latency
- Column-family (Cassandra, Bigtable): wide tables optimized for write throughput
- Graph (Neo4j): relationships as first-class citizens
The real question is not “SQL or not SQL” but “what does my access pattern look like?”
The case for relational
Relational databases are the most successful software in history for good reasons. They give you:
- Schema and integrity: the database rejects bad data instead of discovering it later
- Transactions: ACID guarantees that make money-related code sane
- Joins: ask about relationships at query time, no pre-shaping needed
- Maturity: decades of tooling, tuning, and expertise; the skills transfer everywhere
-- Relational strength: ask cross-cutting questions freely
SELECT c.name,
SUM(o.total) AS lifetime_value
FROM customers c
JOIN orders o ON o.customer_id = c.id
WHERE o.status = 'paid'
GROUP BY c.id
ORDER BY lifetime_value DESC
LIMIT 10;
For anything with money, integrity, or unpredictable reporting needs, relational is the boring correct answer. PostgreSQL specifically has grown beyond its roots — JSONB gives you document flexibility inside a relational database, and UNLOGGED tables, BRIN indexes, and good partitioning cover a lot of the old “SQL can’t scale” objections.
The case for document stores
Document databases optimize for the opposite thing: the shape of data you read matches the shape you store. No joins, no mapping layer, just write a JSON document and read it back.
// Document model: embed what you read together
{
"_id": "ord_1001",
"customer": { "name": "Ada", "email": "ada@example.com" },
"items": [
{ "sku": "KB-01", "qty": 2, "price": 19.99 },
{ "sku": "MS-02", "qty": 1, "price": 89.00 }
],
"total": 128.98
}
This wins when:
- Your documents have variable or evolving shape (products with different attribute sets)
- You read whole aggregates (an order with its items) more than you cross-reference
- You want to ship faster without migration pain in the early days
// MongoDB: read the whole aggregate in one query
const order = await db.orders.findOne({ _id: "ord_1001" });
// order already contains items — no join, no mapping
The costs appear later: cross-document consistency is your problem, ad-hoc reporting requires aggregation pipelines, and “what if I need to ask a question I didn’t anticipate?” becomes painful.
Key-value: the hammer for a specific nail
Key-value stores (Redis, DynamoDB) are not general-purpose databases; they’re latency-critical lookup engines. Session data, caching, leaderboards, feature flags, rate limits.
// Redis: a session lookup that needs to be fast, not fancy
await redis.set(`session:${token}`, JSON.stringify(user), "EX", 86400);
const user = JSON.parse(await redis.get(`session:${token}`));
Use them for what they’re good at, and remember the access pattern is brutally simple: you get a value by a key, full stop. If your question is “give me everything where X,” a key-value store is the wrong shape.
A decision framework
Instead of starting from the database, start from your data:
1. Is the data fundamentally relational? Entities that join together, integrity that must hold, money that must balance → relational. This covers the majority of business software.
2. Is the data a self-contained aggregate? Documents that are read whole, that can tolerate eventual consistency → document store is a legitimate choice.
3. Is it a simple lookup with strict latency? → key-value, and keep your source of truth elsewhere.
4. Do you need to explore relationships freely? (social graphs, recommendation engines) → graph.
5. Do you need massive write throughput with a fixed partition key? → column-family.
The hybrid that wins most arguments
The most important trend of the last decade: the models are converging, and you can mix them in one system.
PostgreSQL + JSONB gives you relational integrity and document flexibility. You can have a relational customers table and a JSONB order document, and query either way. Redis can sit in front of a relational store for cache and session speed. DynamoDB can hold the hot path while an Aurora/Postgres instance holds the canonical data for reporting.
The pragmatic playbook:
- Default to relational (PostgreSQL). It handles 90% of real workloads and keeps your options open.
- Add a key-value cache when latency demands it.
- Add a document/column store only when the read or write pattern demonstrably exceeds what relational can do — measure first.
- Keep the reportable, canonical data somewhere you can ask arbitrary questions of it.
Conclusion
“SQL vs NoSQL” is a 2014 conversation wearing 2026 clothes. The useful question is about your data’s shape and access patterns. Relational is the default for good reason; document and key-value stores win specific, measurable fights; and the best modern systems compose several models deliberately. Choose with data in hand, not with a doctrine in your heart.
Written by
Benmalek Zohir
Founder, AI Engineer & Full Stack Developer
Benmalek Zohir is an AI Engineer, Full Stack Developer, and technology enthusiast focused on artificial intelligence, software development, and emerging technologies. He is the founder of SoftwareJournal.blog, where he shares practical insights, software discoveries, AI tools, and the latest developments in technology.