database

SQL vs NoSQL: How to Choose the Right Database

Learn the real differences between SQL and NoSQL databases. When to use PostgreSQL, MongoDB, Cassandra, or Redis. Practical guide with use cases and tradeoffs.

By Akash Sharma·5 min read
#sql
#nosql
#database
#postgresql
#mongodb
#system design
#backend

You're starting a new project. Someone says "use MongoDB." Someone else says "just use Postgres." Both are confident.

Neither explains why.

Here's how to actually decide.

The Core Difference

SQL databases store data in tables with rows and columns. Relationships between tables use foreign keys and JOINs.

NoSQL databases use other structures: documents (JSON), key-value pairs, wide columns, or graphs. No fixed schema. No JOINs.

plaintext
SQL (PostgreSQL):
users table          orders table
-----------          ------------
id | name | email    id | user_id | total
1  | Alice | a@x.com  1  | 1       | 100
2  | Bob   | b@x.com  2  | 1       | 50
 
NoSQL (MongoDB):
{
  "_id": "1",
  "name": "Alice",
  "email": "a@x.com",
  "orders": [
    {"id": "1", "total": 100},
    {"id": "2", "total": 50}
  ]
}

Neither is better. They model data differently.

When SQL Wins

Relationships between entities matter. Users have orders. Orders have products. Products have categories. SQL handles multi-table queries cleanly.

sql
SELECT u.name, COUNT(o.id) as order_count, SUM(o.total) as revenue
FROM users u
JOIN orders o ON u.id = o.user_id
WHERE o.created_at > '2025-01-01'
GROUP BY u.id
ORDER BY revenue DESC;

Try writing this query with MongoDB's aggregation pipeline. It works, but it's much more verbose.

ACID transactions are required. Bank transfers. Inventory updates. Anything where partial writes are catastrophic.

sql
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;
-- If anything fails, both updates roll back

Schema is stable. Your data model doesn't change weekly. SQL's rigid schema is a feature — it enforces consistency.

Use SQL for: E-commerce (orders, inventory, users), financial systems, CRMs, content management, anything with complex reports.

When NoSQL Wins

Schema varies per record. A product catalog where TVs have different fields than shoes. SQL needs nullable columns or a flexible JSON column. Document databases handle this naturally.

json
// TV
{"type": "tv", "screen_size": 55, "resolution": "4K", "hdmi_ports": 4}
 
// Shoe  
{"type": "shoe", "size": 10, "material": "leather", "color": "black"}

Massive scale with simple access patterns. If you always look up data by a single key (user ID, session ID), key-value stores like DynamoDB or Redis are 10x faster than SQL for this.

Write-heavy workloads at huge scale. Cassandra handles millions of writes per second by sacrificing JOINs and strong consistency. No SQL database matches this write throughput.

Flexible iteration early in a project. Changing schema in SQL means migrations. In MongoDB, you just add a field.

The NoSQL Categories

Different problems need different NoSQL types:

Document (MongoDB, CouchDB): JSON documents. Good for content, catalogs, user profiles. Flexible schema.

Key-Value (Redis, DynamoDB): Lookup by key. Extremely fast. Good for sessions, caches, leaderboards.

Wide-Column (Cassandra, HBase): Rows with many columns, partitioned for massive scale. Good for time-series, IoT, analytics.

Graph (Neo4j, Amazon Neptune): Nodes and edges. Good for social networks, recommendation engines, fraud detection.

Real Examples

Airbnb: Uses MySQL for bookings and payments (ACID required), but Elasticsearch for search (full-text, flexible), and Redis for caching.

Instagram: PostgreSQL for user data and posts. Cassandra for feed data at scale.

Uber: MySQL for trips and users. Redis for real-time driver locations.

Most production systems use multiple databases — the right tool for each job.

PostgreSQL Does a Lot of Both

Modern PostgreSQL blurs the line. It has:

  • JSONB column type (store documents with indexing)
  • Full-text search
  • Arrays and nested data
  • Excellent performance at scale

For most apps (millions of users, not billions), PostgreSQL handles use cases you might have reached for MongoDB for.

sql
-- Store flexible product attributes as JSONB
CREATE TABLE products (
  id SERIAL PRIMARY KEY,
  name TEXT,
  category TEXT,
  attributes JSONB  -- {"screen_size": 55, "resolution": "4K"}
);
 
-- Query inside JSON — indexed and fast
SELECT * FROM products
WHERE attributes->>'screen_size' = '55'
  AND category = 'tv';

This approach keeps your data in SQL (with transactions and JOINs) while handling variable schemas.

The Decision Framework

plaintext
Need ACID transactions?              → SQL
Complex queries with JOINs?         → SQL
Data model is clear and stable?     → SQL
Single-digit millisecond lookups?   → Key-Value (Redis, DynamoDB)
Write millions of events per second? → Wide-Column (Cassandra)
Flexible JSON, nested data?         → Document (MongoDB) or PostgreSQL JSONB
Graph relationships?                → Graph DB (Neo4j)

When in doubt, start with PostgreSQL. You can always add a specialized database later when you have a concrete performance problem.

Key Takeaways

  • SQL: tables, relationships, JOINs, ACID transactions — great for structured, related data
  • NoSQL: flexible schemas, no JOINs, often scales horizontally — great for specific patterns
  • Document DBs (MongoDB): variable schemas, nested data
  • Key-Value (Redis, DynamoDB): fast single-key lookups
  • Wide-Column (Cassandra): massive write throughput
  • PostgreSQL handles most use cases — start there, add specialized DBs as needed
  • Most large systems use multiple databases for different workloads

SQL vs NoSQL is the wrong question. The right question: what are your access patterns and consistency requirements?

Related reading: Database Indexing Explained · Database Sharding Explained · CAP Theorem Explained

Enjoyed this article?

Get weekly insights on backend architecture, system design, and Go programming.