π This is Part 3 of the βScaling Your APIβ Series
- Part 1: Performance & Infrastructure β - Technical techniques to handle millions of requests
- Part 2: Design & Architecture β - Organizational strategies and API design patterns
- Part 3 (this page): Choosing the Right Database - Database selection for your API
- Part 4: Load Balancing & High Availability β - Keeping your API always available
- Part 5: Monitoring & Performance β - Tracking and improving API performance
Youβve designed your API and thought about scaling strategies. Now comes the most critical decision: choosing the right database. Your database choice will determine your APIβs speed, scalability, and reliability.
Think of it like this: Your API is a restaurantβs waitstaff, and your database is the kitchen. Even the best waiters canβt serve food fast if the kitchen is slow!
Why Database Selection Matters for APIs
When building APIs, your database directly impacts:
- Response Time: Can you respond in < 100ms?
- Throughput: Can you handle 10,000 requests/second?
- Concurrency: Can 1,000 users access data simultaneously?
- Scalability: Can you grow from 1K to 1M users?
- Reliability: What happens if your database crashes?
The harsh truth: A bad database choice can kill your APIβs performance, no matter how well-designed your code is.
The API Database Landscape
(CRUD operations)"] START --> REALTIME["Real-time API
(live updates)"] START --> SEARCH["Search API
(text queries)"] START --> ANALYTICS["Analytics API
(aggregations)"] REST --> SQL["SQL Database
(PostgreSQL)"] REALTIME --> COMBO["NoSQL + Cache
(MongoDB + Redis)"] SEARCH --> ELASTIC["Search Engine
(Elasticsearch)"] ANALYTICS --> COLUMNAR["Column Store
(Cassandra/ClickHouse)"] style START fill:#dbeafe,stroke:#2563eb style SQL fill:#d1fae5,stroke:#059669 style COMBO fill:#fef3c7,stroke:#d97706 style ELASTIC fill:#fce7f3,stroke:#db2777 style COLUMNAR fill:#e0e7ff,stroke:#6366f1
API Performance Requirements
Before choosing a database, understand your APIβs performance needs:
| Metric | Low Volume | Medium Volume | High Volume |
|---|---|---|---|
| Requests/sec | < 100 | 100 - 10,000 | > 10,000 |
| Response Time | < 500ms | < 200ms | < 100ms |
| Concurrent Users | < 1,000 | 1,000 - 100,000 | > 100,000 |
| Data Size | < 10 GB | 10 GB - 1 TB | > 1 TB |
| Database Choice | Any SQL | SQL + Cache | NoSQL + Cache + CDN |
Key Insight: Most APIs start in βLow Volumeβ and need to scale. Choose a database that can grow with you!
1. Relational Databases (SQL) β The API Workhorse
For APIs: The default choice for 90% of REST APIs. Reliable, proven, and powerful.
Perfect For These API Endpoints
GET /api/users/:id β Fast single record lookup
GET /api/orders?userId=123 β Filtered queries with relationships
POST /api/checkout β Transactions (all-or-nothing)
PUT /api/users/:id β Updates with validation
API Performance Characteristics
| Metric | Performance |
|---|---|
| Read Latency | 1-10ms (with proper indexes) |
| Write Latency | 5-50ms |
| Concurrent Connections | 100-1,000 (single server) |
| Throughput | 1,000-10,000 req/sec |
| Scalability | Vertical (bigger server) |
When to Use for Your API
- β Your API serves structured data (users, orders, products)
- β You need ACID transactions (payments, bookings)
- β Your data has relationships (users β orders β products)
- β You need complex queries (filtering, sorting, joining)
- β Your API handles < 10,000 requests/second
When to Consider Alternatives
- β You need > 100,000 requests/second
- β Your API response time > 100ms even with optimization
- β Your data model changes every week
- β You need to scale horizontally across 100+ servers
Popular Options for APIs
| Database | API Response Time | Scaling | Best For |
|---|---|---|---|
| PostgreSQL | 5-20ms | Vertical (10K req/s) | Most REST APIs, complex queries |
| MySQL | 3-15ms | Vertical (15K req/s) | Simple CRUD APIs, read-heavy |
| CockroachDB | 10-50ms | Horizontal (100K+ req/s) | Global APIs, multi-region |
| Amazon Aurora | 5-20ms | Auto-scaling | AWS-based APIs, serverless |
| PlanetScale | 5-15ms | Serverless scaling | Modern APIs, easy scaling |
π‘ API Recommendation: Start with PostgreSQL. Migrate to CockroachDB/Aurora when you outgrow a single server.
API Code Example
// Express.js API with PostgreSQL
app.get('/api/users/:id', async (req, res) => {
const user = await db.query(
'SELECT * FROM users WHERE id = $1',
[req.params.id]
);
res.json(user); // Typical response time: 5-20ms
});
// With proper indexing + connection pooling:
// - Handles 5,000-10,000 requests/second
// - 95th percentile latency < 50ms
2. Document Databases (NoSQL) β Flexible & Fast
For APIs: Choose when your API needs flexibility and high write throughput.
What They Store
Documents (usually JSON format) that can have different fields.
Real-World Example:
// User 1 (has address)
{
"name": "John",
"email": "john@example.com",
"address": {
"city": "NYC",
"country": "USA"
}
}
// User 2 (no address, has phone)
{
"name": "Jane",
"email": "jane@example.com",
"phone": "+1-555-0123"
}
API Performance Characteristics
| Metric | Performance |
|---|---|
| Read Latency | 1-5ms |
| Write Latency | 1-10ms |
| Concurrent Connections | 10,000+ |
| Throughput | 50,000-500,000 req/sec |
| Scalability | Horizontal (add servers) |
When to Use for Your API
- β Your API serves flexible data (user profiles, product catalogs)
- β You need high write throughput (logging, analytics)
- β Your API needs to scale horizontally
- β Your data is naturally nested (user β settings β preferences)
- β Youβre building fast and iterating quickly
When to Stick with SQL
- β You need complex joins across tables
- β You need strong ACID transactions (payments)
- β Your team is unfamiliar with NoSQL
- β Your data is highly relational
Popular Options for APIs
| Database | API Response Time | Scaling | Best For |
|---|---|---|---|
| MongoDB | 2-10ms | Horizontal | General-purpose APIs, flexible data |
| Amazon DynamoDB | 1-5ms | Auto-scaling | Serverless APIs, AWS Lambda |
| Firebase/Firestore | 50-200ms | Auto-scaling | Mobile APIs, real-time sync |
| Couchbase | 1-5ms | Horizontal | High-performance APIs, caching |
π‘ API Recommendation: MongoDB for self-hosted, DynamoDB for serverless AWS APIs.
API Code Example
// Express.js API with MongoDB
app.get('/api/products/:id', async (req, res) => {
const product = await Product.findById(req.params.id);
res.json(product); // Response time: 2-10ms
});
// Benefits for APIs:
// - Schema flexibility (add fields anytime)
// - Fast reads/writes (1-10ms)
// - Easy horizontal scaling
// - Handles 50K+ requests/second
3. Key-Value Stores β API Speed Boost
For APIs: Essential for caching and reducing database load. Can turn 50ms responses into 1ms responses!
What Theyβre Good For
Lightning-fast storage and retrieval of simple data.
Real-World Example:
Key: "session:abc123"
Value: {"user_id": 456, "logged_in": true}
Key: "cart:user456"
Value: ["item1", "item2", "item3"]
API Performance Characteristics
| Metric | Performance |
|---|---|
| Read Latency | < 1ms (sub-millisecond) |
| Write Latency | < 1ms |
| Concurrent Connections | 100,000+ |
| Throughput | 1,000,000+ req/sec |
| Scalability | Horizontal |
When to Use for Your API
- β Caching: Store frequently accessed data (80% of API calls hit cache)
- β Session Management: Store user sessions, JWT tokens
- β Rate Limiting: Track API request counts per user
- β Real-time Features: Leaderboards, counters, live updates
- β Reduce Database Load: Cache database query results
When NOT to Use as Primary Database
- β You need to query/filter data
- β You need data persistence guarantees
- β You need complex queries
Popular Options for APIs
| Database | API Response Time | Use Case |
|---|---|---|
| Redis | < 1ms | API caching, sessions, rate limiting |
| Memcached | < 1ms | Simple API caching only |
| Amazon ElastiCache | < 1ms | AWS API caching |
| Dragonfly | < 0.5ms | Drop-in Redis replacement (faster) |
π‘ API Recommendation: Every API should use Redis for caching. Period.
API Code Example
// API with Redis caching
app.get('/api/products/:id', async (req, res) => {
// Try cache first
const cached = await redis.get(`product:${req.params.id}`);
if (cached) {
return res.json(JSON.parse(cached)); // 1ms response!
}
// Cache miss: query database
const product = await db.query('SELECT * FROM products WHERE id = $1');
// Store in cache for 5 minutes
await redis.setex(`product:${req.params.id}`, 300, JSON.stringify(product));
res.json(product); // 20ms first time, 1ms afterwards
});
// Result: 80% of requests served from cache = 20x faster!
4. Column-Family Stores
Think of it like: Instead of storing entire rows together, you store columns together. Great for reading specific columns from billions of rows.
What Theyβre Good For
Massive amounts of data where you read specific columns.
Real-World Example:
Instead of storing:
[John, 25, NYC] [Jane, 30, LA] [Bob, 28, CHI]
Store like:
Names: [John, Jane, Bob]
Ages: [25, 30, 28]
Cities: [NYC, LA, CHI]
When to Use
- β You have billions of rows
- β You query specific columns (not full rows)
- β Time-series data (sensor readings, logs)
- β You need to write massive amounts of data fast
When NOT to Use
- β You frequently need entire rows
- β You have complex queries with joins
- β Your data fits in memory
Popular Options
| Database | Best For | Used By |
|---|---|---|
| Apache Cassandra | Massive scale, always available | Netflix, Apple, Discord |
| HBase | Hadoop ecosystem | Adobe, Salesforce |
| ScyllaDB | High performance Cassandra alternative | Discord, Comcast |
| Amazon Keyspaces | Managed Cassandra on AWS | AWS customers |
π‘ Best for: Massive scale applications like Netflix or Uber.
5. Search Engines
Think of it like: Google for your data. You can search text, filter, aggregate, and find things super fast.
What Theyβre Good For
Full-text search, log analysis, complex queries.
Real-World Example:
Search: "smartphone under $500"
Results: All phones matching criteria, sorted by relevance
Search logs: "ERROR" in the last hour
Results: All error logs with context
When to Use
- β You need full-text search (search boxes on websites)
- β You need to analyze logs (find errors, patterns)
- β You need faceted search (filters on e-commerce sites)
- β You need autocomplete, fuzzy matching, suggestions
When NOT to Use
- β As your primary database (use it alongside one)
- β For transactional data
- β When you donβt need search features
Popular Options
| Database | Best For | Used By |
|---|---|---|
| Elasticsearch | Modern choice, great features | Netflix, Uber, Microsoft |
| Apache Solr | Enterprise search | Apple, Netflix, AT&T |
| Amazon OpenSearch | Managed Elasticsearch on AWS | AWS customers |
| Algolia | Instant search-as-a-service | Twitch, Stripe, Slack |
π‘ Most popular: Elasticsearch β powerful, scalable, great ecosystem.
6. Graph Databases
Think of it like: Facebookβs friend network. Itβs all about relationships β who knows who, whatβs connected to what.
What Theyβre Good For
Data where relationships are as important as the data itself.
Real-World Example:
John --[FRIENDS_WITH]--> Jane
Jane --[WORKS_AT]--> Google
Google --[LOCATED_IN]--> California
John --[LIKES]--> Pizza
Jane --[LIKES]--> Pizza
When to Use
- β Social networks (who knows who)
- β Recommendation engines (people who bought X also bought Y)
- β Fraud detection (finding suspicious patterns)
- β Knowledge graphs (how concepts relate)
When NOT to Use
- β Simple data without complex relationships
- β You just need to store and retrieve records
- β You donβt need to traverse relationships
Popular Options
| Database | Best For | Used By |
|---|---|---|
| Neo4j | Most popular, great tools | eBay, Walmart, NASA |
| Amazon Neptune | Managed graph on AWS | AWS customers |
| ArangoDB | Multi-model (graph + document) | Startups |
| TigerGraph | Large-scale analytics | Banks, healthcare |
π‘ Start here: Neo4j β excellent documentation and community.
7. Time-Series Databases
Think of it like: A database optimized for data that changes over time β like temperature readings every minute or stock prices every second.
What Theyβre Good For
Data thatβs timestamped and constantly arriving.
Real-World Example:
2024-01-01 10:00:00 | Temperature: 72Β°F
2024-01-01 10:01:00 | Temperature: 72.5Β°F
2024-01-01 10:02:00 | Temperature: 73Β°F
When to Use
- β IoT sensor data (temperature, pressure, motion)
- β Application metrics (CPU, memory, requests)
- β Financial data (stock prices, trades)
- β You need to analyze trends over time
When NOT to Use
- β Your data isnβt timestamped
- β You donβt analyze time-based patterns
- β You rarely query by time ranges
Popular Options
| Database | Best For | Used By |
|---|---|---|
| InfluxDB | General purpose, easy to use | Cisco, IBM, eBay |
| TimescaleDB | PostgreSQL extension | Comcast, IBM, Walmart |
| Prometheus | Monitoring and alerting | SoundCloud, Docker |
| Amazon Timestream | Managed on AWS | AWS customers |
π‘ Best choice: InfluxDB for IoT, TimescaleDB if you already use PostgreSQL.
8. Vector Databases
Think of it like: A database for AI. Stores data as numbers (vectors) and finds similar items super fast.
What Theyβre Good For
AI/ML applications, similarity search, recommendations.
Real-World Example:
"Find images similar to this photo"
"Find products similar to what this user liked"
"Find documents related to this topic"
When to Use
- β Building AI-powered search (ChatGPT-like features)
- β Recommendation systems (similar products/content)
- β Image/video similarity search
- β Semantic search (search by meaning, not keywords)
When NOT to Use
- β Youβre not building AI features
- β You donβt need similarity search
- β Traditional keyword search is enough
Popular Options
| Database | Best For | Used By |
|---|---|---|
| Pinecone | Easiest, fully managed | AI startups |
| Weaviate | Open source, flexible | Enterprises |
| Milvus | High performance, scalable | AI companies |
| Qdrant | Fast, modern | ML applications |
| pgvector | PostgreSQL extension | Existing Postgres users |
π‘ Trending: Pinecone for ease of use, pgvector if you want to stay in PostgreSQL.
9. In-Memory Databases
Think of it like: Everything stored in RAM (super fast memory) instead of disk. Like keeping your tools in your hand instead of in the garage.
What Theyβre Good For
Extreme speed when you need microsecond response times.
When to Use
- β High-frequency trading (stocks)
- β Real-time bidding (ads)
- β Gaming leaderboards
- β Fraud detection (real-time)
When NOT to Use
- β You have huge amounts of data (RAM is expensive)
- β Speed isnβt critical
- β You need data to persist long-term
Popular Options
| Database | Best For | Used By |
|---|---|---|
| Redis | Caching, data structures | Twitter, GitHub |
| Memcached | Simple caching | Facebook, Wikipedia |
| Apache Ignite | Distributed computing | Banks, retail |
| VoltDB | High-speed transactions | Telecom, finance |
π‘ Most common: Redis (itβs both key-value AND in-memory).
Quick Decision Tree
structured in tables?"} Q1 --> |"Yes"| Q2{"Need to scale
to billions of records?"} Q2 --> |"No"| SQL["PostgreSQL
or MySQL"] Q2 --> |"Yes"| SCALE["Cassandra
or CockroachDB"] Q1 --> |"No"| Q3{"What type of data?"} Q3 --> |"Flexible documents"| MONGO["MongoDB"] Q3 --> |"Just key-value pairs"| REDIS["Redis"] Q3 --> |"Time-series"| INFLUX["InfluxDB"] Q3 --> |"Relationships/Network"| NEO4J["Neo4j"] Q3 --> |"Text/logs to search"| ELASTIC["Elasticsearch"] Q3 --> |"AI/embeddings"| VECTOR["Pinecone"] style START fill:#dbeafe,stroke:#2563eb style SQL fill:#d1fae5,stroke:#059669 style MONGO fill:#fef3c7,stroke:#d97706 style ELASTIC fill:#fce7f3,stroke:#db2777
Real-World API Architectures
Scenario 1: E-Commerce API (10,000 req/s)
API Endpoints:
GET /api/products β List products
GET /api/products/:id β Get product details
POST /api/checkout β Process order
GET /api/search?q=laptop β Search products
Database Stack:
PostgreSQL: Store products, users, orders
- Response time: 10-20ms
- Connection pool: 100
Redis: Cache product details, shopping carts
- Response time: 1ms
- Hit rate: 80%
Elasticsearch: Product search API
- Response time: 50-100ms
- Handles complex queries
Result: Average API response time: 5-15ms
Scenario 2: Social Media API (100,000 req/s)
API Endpoints:
GET /api/feed β Get user feed
POST /api/posts β Create post
GET /api/users/:id β Get profile
GET /api/notifications β Get notifications
Database Stack:
MongoDB: User profiles, posts (flexible schema)
- Write: 2-5ms
- Read: 2-10ms
- Sharded across 10 servers
Redis: Real-time notifications, session cache
- Response time: < 1ms
- Pub/sub for live updates
Cassandra: Activity logs (high write volume)
- Write: 1-2ms
- Handles 500K writes/sec
Result: API handles 100K+ requests/second
Scenario 3: Analytics API (High Volume Reads)
API Endpoints:
GET /api/metrics?timeRange=7d β Get metrics
GET /api/reports/:id β Get report
POST /api/events β Log event
Database Stack:
ClickHouse: Time-series analytics
- Query time: 100-500ms
- Billion rows in seconds
PostgreSQL: Metadata, user accounts
- Response time: 5-15ms
Redis: Cache aggregated results
- Response time: 1ms
- Cache for 5 minutes
Result: Complex analytics served in < 200ms
Scenario 4: Banking API (ACID Critical)
API Endpoints:
POST /api/transfer β Transfer money
GET /api/balance β Get balance
GET /api/transactions β Transaction history
Database Stack:
PostgreSQL: Primary database (ACID guarantee)
- All transactions in DB transactions
- Response time: 20-50ms
- Read replicas for scaling
Redis: Session management only
- No financial data in cache!
TimescaleDB: Transaction history analysis
- Fast time-series queries
Result: 100% data integrity, 10K req/s
Comparison Table
| Database Type | Speed | Scalability | Complexity | Best Use Case |
|---|---|---|---|---|
| SQL (PostgreSQL) | Medium | Medium | Low | Most applications |
| Document (MongoDB) | Fast | High | Medium | Flexible data |
| Key-Value (Redis) | Very Fast | High | Very Low | Caching |
| Column (Cassandra) | Fast | Very High | High | Massive scale |
| Search (Elasticsearch) | Fast | High | Medium | Search & logs |
| Graph (Neo4j) | Medium | Medium | Medium | Relationships |
| Time-Series (InfluxDB) | Fast | High | Low | Sensor data |
| Vector (Pinecone) | Fast | High | Medium | AI features |
Common Mistakes to Avoid
β Mistake 1: Using MongoDB When You Need PostgreSQL
Bad: Using MongoDB for highly structured, relational data
Good: Use PostgreSQL when data has clear relationships
Why: MongoDB is great for flexibility, but if your data is structured, SQL databases are simpler and more powerful.
β Mistake 2: Using PostgreSQL as a Cache
Bad: Caching frequently accessed data in PostgreSQL
Good: Use Redis for caching, PostgreSQL for persistent data
Why: Redis is 10-100x faster for caching.
β Mistake 3: Using Elasticsearch as Primary Database
Bad: Storing all your data only in Elasticsearch
Good: Store in PostgreSQL/MongoDB, sync to Elasticsearch for search
Why: Elasticsearch is a search engine, not a database. Use it alongside your primary database.
β Mistake 4: Choosing Based on Hype
Bad: "Everyone uses MongoDB, let's use it!"
Good: Analyze your actual needs and choose accordingly
Why: Popular doesnβt mean right for your use case.
The Safe Default API Stack
If youβre just starting your API and unsure, this stack works for 90% of APIs:
Primary Database: PostgreSQL
- All your main data
- Response time: 5-20ms
- Handles 5,000-10,000 req/s
Cache Layer: Redis
- Cache hot data (80% hit rate)
- API sessions, rate limiting
- Response time: < 1ms
Search (optional): Elasticsearch
- Only if you need search endpoints
- Response time: 50-100ms
Why this works for APIs:
- β PostgreSQL handles complex queries, transactions, relationships
- β Redis reduces database load by 80% and speeds up responses 20x
- β Together they handle 10,000+ requests/second easily
- β Can scale vertically (bigger servers) to 50,000 req/s
- β Battle-tested by thousands of companies
Performance with this stack:
Without Redis: 50ms average response time
With Redis: 5ms average response time (10x faster!)
Database load: Reduced by 80%
API Scaling Path: When to Add/Switch Databases
Grow your database stack as your API scales:
Phase 1: Starting Out (0-100 req/s)
βββ PostgreSQL
Performance: 10-50ms response time
Complexity: Low
Cost: $20-50/month
Phase 2: Getting Traction (100-5,000 req/s)
βββ PostgreSQL (add indexes, connection pooling)
βββ Redis (cache hot data)
Performance: 5-15ms response time
Complexity: Medium
Cost: $100-300/month
Phase 3: Growing Fast (5,000-50,000 req/s)
βββ PostgreSQL (read replicas, bigger server)
βββ Redis (cache + session management)
βββ Elasticsearch (if you have search endpoints)
Performance: 2-10ms response time
Complexity: Medium-High
Cost: $500-2,000/month
Phase 4: High Scale (50,000-500,000 req/s)
βββ PostgreSQL (for critical transactional data)
βββ MongoDB or Cassandra (for high-volume data)
βββ Redis (distributed cache)
βββ Elasticsearch (for search)
Performance: 1-5ms response time
Complexity: High
Cost: $5,000-20,000/month
Phase 5: Massive Scale (500,000+ req/s)
βββ PostgreSQL / CockroachDB (critical data)
βββ Cassandra / ScyllaDB (high-volume writes)
βββ Redis Cluster (distributed caching)
βββ Elasticsearch Cluster (search)
βββ ClickHouse (analytics)
Performance: < 1ms response time
Complexity: Very High
Cost: $50,000+/month
Key principle for APIs: Only add complexity when your current setup canβt handle the load!
Summary: Database Selection for APIs
Quick Takeaways for API Developers:
- Starting your API? β PostgreSQL + Redis (handles 10K req/s)
- Need search endpoints? β Add Elasticsearch
- Flexible data model? β Consider MongoDB
- Need 100K+ req/s? β Add Cassandra or MongoDB sharding
- Real-time features? β Redis pub/sub
- Analytics endpoints? β Consider ClickHouse or TimescaleDB
- AI-powered API? β Add pgvector or Pinecone
The Golden Rule for APIs
Start with PostgreSQL + Redis. This combo handles 95% of APIs up to 10,000 requests/second. Only add more databases when you hit specific bottlenecks.
API Performance Checklist
Before adding another database, optimize what you have:
- Added database indexes on filtered/sorted columns
- Implemented Redis caching (80% hit rate = 5x faster)
- Using connection pooling (100-200 connections)
- Optimized slow queries (use EXPLAIN)
- Added read replicas for read-heavy endpoints
- Implemented API rate limiting
- Using CDN for static data
Most slow APIs have poorly optimized databases, not the wrong database!
Continue the Series
This is Part 3 of the βScaling Your APIβ series:
- Part 1: Performance & Infrastructure β - Technical techniques to handle millions of requests
- Part 2: Design & Architecture β - Organizational strategies and API design patterns for large-scale systems
- Part 3: Choosing the Right Database β You are here
- Part 4: Load Balancing & High Availability β - Keeping your API always available
- Part 5: Monitoring & Performance β - Tracking and improving API performance
Further Reading
- PostgreSQL Official Docs β Learn the most versatile database
- MongoDB University β Free courses on document databases
- Redis Documentation β Master caching and real-time data
- Elasticsearch Guide β Learn search and analytics
- Database Rankings β See popularity trends
Remember: The best database for your API is the one that meets your performance requirements simply. Premature optimization is the root of all evil β but so is choosing the wrong database!