System Architecture

Datastore Placement Strategy — Combining RDBMS / NoSQL / Cache / Search

Datastore Placement Strategy — Combining RDBMS / NoSQL / Cache / Search

About this article

This article is the sixth deep dive in the “System Architecture” category of the Architecture Crash Course for the Generative-AI Era series, covering the overall placement strategy for datastores.

In 2026, combining RDBMS, KVS, search engines, time-series DBs, vector DBs, and object storage by use case is the default. “What goes where” decides operating cost and latency. This article focuses on the system-wide placement strategy — category overviews, Polyglot Persistence, scaling, and backup design (per-app deep selection lives in the “Data Architecture” category).

What is a datastore in the first place

A datastore is, roughly speaking, “the collective term for mechanisms that store and retrieve data for an application.”

Imagine a library. Books go on shelves (RDBMS) in orderly rows, frequently referenced dictionaries sit on the counter (cache), and posters and photos go in a separate warehouse (object storage). Stuffing everything in one place makes it overflow and unsearchable — choosing the right storage location per use is what datastore placement strategy is about.

Scope of this article

Datastore selection happens in two stages: “the system-architecture-level overall strategy” and “the per-application detailed selection in application architecture.” This article focuses on the former: system-wide what-goes-where.

ArticleScope
This article (system-architecture overall strategy)Overall placement, category overviews, Polyglot Persistence, scaling
Per-app detailed selection (separate category)Per-app detailed selection, decision flow, volume-based steps
Data modeling (separate category)Table design, normalization, primary keys, indexes
Data platform (separate category)DWH, data lake, BI integration

This article’s stance is the overall map for “how to combine RDBMS, NoSQL, cache, search, and object storage at system-architecture design time.” Concrete selection flows by data volume and functional requirements live in the “Data Architecture” category.

The question this article answers is “which datastore types to combine.” Specific selection flows go deeper in another category.

The least reversible decision

Datastore selection is the most irreversible judgment in system architecture. Application code can be rewritten, but DB migration after schemas and large data have piled up is orders of magnitude heavier — sometimes unavoidable days to weeks of downtime.

Covering everything with the familiar RDBMS alone is no longer the modern way. The current default combines RDBMS, NoSQL, cache, search, and object storage. “What you picked here” dictates the next 5-10 years.

This is a domain where “think about it later” doesn’t work. The first decision matters.

The four major categories

CategoryUseExamples
RDBMSStructured data, integrity priorityPostgreSQL, MySQL
NoSQLScale priority, flexible schemaDynamoDB, MongoDB
CacheHigh-speed access, transient dataRedis, Memcached
Search engineFull-text search, aggregationElasticsearch, OpenSearch

Plus object storage (S3, etc.) for images, videos, attachments. The design sense of “which data goes where” decides app-wide performance and operating cost.

RDBMS

RDBMS stores data in tables and operates on it via SQL. ACID transactions (Atomicity, Consistency, Isolation, Durability) guarantee strong consistency, with overwhelming track record in finance and business apps where data correctness is non-negotiable.

ProductTraitFits
PostgreSQLOSS standard, JSON / full-text / GIS supportFirst choice for new development
MySQLAdoption, lightweight, info densityWeb services, legacy compatibility
MariaDBMySQL fork, fully OSSMySQL alternative, commercial avoidance
Oracle DatabaseEnterprise, feature-richFinance, core systems
SQL ServerTight Microsoft integration.NET / Windows
Amazon AuroraMySQL/PG compatible, cloud-optimizedNew AWS builds

For new projects, PostgreSQL is the default unless there’s a specific reason. JSON type, full-text search, GIS make it stand out in OSS for capability and extensibility. MySQL still works on legacy web services but new selections almost always favor PostgreSQL.

The first choice for new is PostgreSQL. When in doubt, start here.

The four NoSQL families

NoSQL (“Not Only SQL”) covers everything beyond RDBMS. The core traits are scale and flexible structure, splitting into four families:

FamilyExamplesStrong at
KVS (key-value)Redis / DynamoDB / MemcachedCache, sessions
DocumentMongoDB / DocumentDB / FirestoreJSON, hierarchical data
Wide-columnCassandra / HBase / BigTableTime-series, write-heavy
GraphNeo4j / NeptuneSocial, relationship analysis

NoSQL’s basic philosophy: “sacrifice RDBMS-grade integrity to scale.” Workloads like e-commerce catalogs, social-feed history, IoT logs — “large volumes written fast” — are where NoSQL shines. Conversely, picking it for an integrity-critical business app is a bad fit.

DynamoDB and Redis

DynamoDB (AWS) and Redis are the two most-used NoSQL products in real work. Both are KVS but with clearly different strong suits.

DynamoDB is a fully managed distributed KVS“write without thinking about scale” is the headline. It scales theoretically without limit and pairs well with serverless, often picked for high-traffic APIs. Joins and aggregation are weak; the mental model flips from RDBMS — “decide access patterns first, design tables second.”

Redis is the de facto in-memory cache. Sub-millisecond responses from in-memory data; broad utility for sessions, page cache, rate limiting, ranking (ZSET), Pub/Sub.

UseRecommended
Fixed-pattern, large-scale writesDynamoDB
Sessions, page cacheRedis / ElastiCache
Real-time leaderboards / rankingsRedis (ZSET)

DynamoDB for scale, Redis for cache. Different roles.

Search engines

Search engines are specialized DBs for fast searches across text content (articles, product descriptions). RDBMS LIKE '%kw%' is possible but unusable past tens of thousands of rows; the standard is to bring in a dedicated search engine.

ProductTraitFits
Elasticsearch / OpenSearchFull-text de facto, also log analyticsSerious search, log aggregation
Meilisearch / TypesenseLightweight, modern, easy setupSmall/mid apps
PostgreSQL full-textNo extra DB needed; pg_bigm and similarSmall scale, easy start
AlgoliaManaged SaaS, rich UISpeed-priority services

Japanese full-text search hinges on morphological analysis (Kuromoji) configuration. Without proper dictionaries, “Tokyo Metropolis” gets split into “Tokyo” and “Metropolis” with cascading missed matches.

Object storage

Object storage holds images, videos, PDFs, etc. Putting images directly into RDBMS bloats the DB and tanks performance — “metadata in RDBMS, blobs in object storage” is the basic split. Not following this is a textbook landmine.

ServiceProviderTrait
Amazon S3AWSIndustry de facto, rich integrations
Azure Blob StorageAzureStrong tiered storage
Google Cloud StorageGCPStrong BigQuery integration
Cloudflare R2CloudflareFree egress, low cost

Combined with CDN (CloudFront, etc.), delivery speed and traffic-cost reduction work together. Cloudflare R2 is S3-compatible without bandwidth charges, drawing attention for bandwidth-dominated workloads like video.

Selection by use

Combining datastores by role is the modern default. Typical configurations:

UseRecommended
Transaction-centric appsPostgreSQL / Aurora
Fast sessions / cacheRedis / ElastiCache
Fixed-key ultra-scale writesDynamoDB
Product search / log aggregationOpenSearch / Elasticsearch
Time-series metricsTimestream / InfluxDB
Images, videos, attachmentsS3 / R2 (object storage)
Analytics / BI (Business Intelligence)BigQuery / Redshift / Snowflake

Combining the right DB per use is called Polyglot Persistence.

Polyglot Persistence

Polyglot Persistence is the design philosophy of using multiple datastores in one system. “One DB for everything” looks tidy on paper, but matching the right DB to each use beats it on performance, cost, and ops.

flowchart LR
    APP([App])
    PG[(PostgreSQL<br/>Master, orders, users)]
    RD[(Redis<br/>Sessions, cache)]
    OS[(OpenSearch<br/>Product search, log aggregation)]
    S3[(S3<br/>Images, videos, attachments)]
    DDB[(DynamoDB<br/>High-throughput logs)]
    APP -->|RDB| PG
    APP -->|KVS| RD
    APP -->|Full-text| OS
    APP -->|Files| S3
    APP -->|Time-series| DDB
    classDef app fill:#fef3c7,stroke:#d97706;
    classDef rdb fill:#dbeafe,stroke:#2563eb;
    classDef kvs fill:#fee2e2,stroke:#dc2626;
    classDef search fill:#fae8ff,stroke:#a21caf;
    classDef obj fill:#f0f9ff,stroke:#0369a1;
    class APP app;
    class PG rdb;
    class RD kvs;
    class OS search;
    class S3,DDB obj;

For e-commerce sites and SaaS products this kind of role-split is essentially standard. Connect the datastores via async message queues (SQS / Kafka) rather than synchronous calls — better for failure isolation. Synchronous chains cascade outages when one DB drops.

“One DB for everything” is past tense. Use the right tool per role.

Scaling and replication

As data and traffic grow, a single server can’t keep up. Replication and sharding are the basic scaling strategies.

MethodMechanismUse
Read replicaAdd read-only copiesRead-heavy apps
ShardingDistribute data across serversDistribute writes too
Multi-AZAvailability-zone redundancyHigh-availability
Multi-regionGeographic redundancy / DRDisaster recovery, global delivery

Cloud-managed DBs (Aurora, Cloud SQL, Cosmos DB) let you toggle these complex configurations with a switch. The operational-cost gap with DIY is overwhelming — “DIY sharding without serious capacity is best left alone” is the practical conclusion.

Backup and restore

Backup strategy is the last line against incidents, mistakes, and ransomware. The point is “can it be restored,” not “is it being taken.” Without periodic restore drills, recovery failures still happen repeatedly.

AspectSubstance
RPO (Recovery Point Objective)How far back can you restore (allowable data loss)
RTO (Recovery Time Objective)How fast you can be back up (allowable downtime)
PITR (Point-in-Time Recovery)Restore to any past instant
Cross-region backupStored in another region for disaster cover
RetentionMeeting legal requirements (e.g. tax: 7 years)

Cloud-managed DBs ship PITR as a standard feature, restorable to any point in the last 5-35 days. Annual / monthly long-term retention often needs separate exports.

DB selection by data volume / traffic

“PostgreSQL by default” is high-accuracy, but the optimum shifts with volume and traffic. Approximations as of April 2026:

VolumeWrite RPSRead RPSRecommended main DBTypical companion
Up to 100k rowsup to 10up to 100PostgreSQL (single)None
Up to 10M rowsup to 100up to 1kPostgreSQL + 1 read replicaRedis (sessions)
Up to 1B rowsup to 1kup to 10kAurora / Cloud SQL + multiple replicasRedis + OpenSearch
Up to 10B rowsup to 10kup to 100kAurora + sharding or DynamoDBRedis + Kafka + ClickHouse
10B rows+10k+100k+DynamoDB / Spanner / CassandraKafka + data lake

Past 10M rows per table, plan index design and partitioning; past 100M rows, consider sharding; past 1B rows, NoSQL becomes a realistic option. Adding cache (Redis) first is often more effective than swapping the DB; verify that cache solves the issue before changing DBs.

When in doubt: PostgreSQL single -> add cache -> add replicas -> shard. Jumping straight to NoSQL is a bad fit.

Schema-change / migration traps

Schema changes are where “DB can’t be changed later” plays out in production. Mistakes here drop production for hours; avoid the forbidden moves rigorously.

Forbidden moveWhy
Rename a column in one migrationOld code on running instances dies instantly. Use expand/contract (add column -> dual write -> switch -> drop old) — three steps
Add NOT NULL column to a 10M+ row table immediatelyExisting rows violate the constraint; migration hangs for hours
CREATE INDEX (non-concurrent) on a hot tableWhole-table lock, writes stop. Use CREATE INDEX CONCURRENTLY (PostgreSQL) or pt-online-schema-change / gh-ost (MySQL)
Apply migrations in production without a backupThe moment something goes wrong, restore is gone
DBA running raw DDL via GUINo change history, no audit, no replay, no rollback
Bundling migration and code deploy in one transactionOn rollback, schema can’t follow back, or follows but old/new code coexists and breaks
Hand-written SQL without a migration tool (Flyway / Liquibase / Prisma Migrate)No version control, no CI verification, prod and dev schemas drift
Picking NoSQL as an RDBMS substituteJoins become necessary and force a major redesign. When transactions are involved, default to RDBMS
Running backups without restore drills”Can’t restore” surfaces during a production incident. Drills are part of ops, not optional
Deploying to production with no-auth / default configThe 2017 MongoDB / Redis / Elasticsearch ransomware attacks encrypted or wiped tens of thousands of nodes with default public exposure

The GitLab DB deletion of January 31, 2017 (an engineer ran rm -rf on the wrong env, all 5 backup methods failed) demonstrates that beyond backup strategy, DB-operation permission and dual-confirmation also matter.

Schema changes always blow up if you skip “migration tool + PR review + staged application.”

AI decision axes

With AI-driven development as the assumption, the deciding axes become “can the schema be managed in code?” and “can AI generate queries / migrations accurately?”

AI-era favorableAI-era unfavorable
PostgreSQL + ORM (Prisma/Drizzle/TypeORM)NoSQL with custom queries (AI struggles)
SQL-based, near-standardVendor GUI data manipulation
Migrations managed in codeSchema kept outside code
DB config managed via Infrastructure as CodeManual console-based DB config
  1. Filter categories by data character (strong / eventual consistency / cache).
  2. Add use-specialized DBs by scale and access pattern (start with normalized DB).
  3. Code-managed schema as an AI-era requirement.
  4. Backup + restore drills as the operational baseline.

The MongoDB “by feel” incident (industry case)

A startup picked MongoDB “to change schema freely,” then six months later started aggregating sales reports from order history — and joins and transactions were suddenly needed everywhere, halting work. Some teams ended up migrating to PostgreSQL and burning three months on the move alone.

Around 2018 I watched a similar case: a startup on MongoDB hit aggregation requirements for orders and couldn’t write the queries; ended up adding daily PostgreSQL sync to feed BI tools.

The lesson: “DB selection isn’t about today’s ease — it’s about a year from now’s requirements.” Especially for transaction-touching apps, default to RDBMS when in doubt. Add NoSQL only when you actually need it. Reversing the order hurts.

“Schemaless is easy” holds until aggregation starts.

What you must decide — what’s your project’s answer?

Articulate your project’s answer in 1-2 sentences for each:

  • Main DB (PostgreSQL / MySQL / Aurora / DynamoDB)
  • Cache strategy (Redis / Memcached / in-app / CDN)
  • Search platform (OpenSearch / PostgreSQL full-text / SaaS)
  • File store (S3 / R2 / Blob Storage)
  • Backup policy (RPO / RTO / retention)
  • Encryption (at-rest, in-transit, key management)
  • Scaling strategy (replicas / sharding / multi-region)

How to record decision reasons

Datastore selection has long-term impact across the entire system. Record why you picked a specific product as an ADR (Architecture Decision Record).

FieldContent
TitleAdopt PostgreSQL as main DB
StatusApproved
ContextNeed to select the main DB for an order-management system. Requirements: transactional consistency + full-text search
DecisionPostgreSQL 16 (Aurora PostgreSQL-compatible)
RationaleACID-compliant for monetary calculations; JSON / full-text / GIS built in, reducing the need for extra DBs; Aurora-compatible for easy read-replica scale-out
Rejected alternativesMySQL: JSON features and partitioning more limited than PostgreSQL. DynamoDB: business requirements need aggregation queries and JOINs
OutcomeStart with PostgreSQL full-text search; add OpenSearch when search volume grows

Months or years later, someone will ask “why PostgreSQL instead of MySQL?” An ADR that answers at a glance is its greatest value.

Summary

This article covered system-architecture-level datastore placement strategy — Polyglot Persistence, scaling, schema-change traps.

For new builds: PostgreSQL-centric, use-specialized additions only as needed (Redis for cache, OpenSearch for search, S3 for blobs). Multi-layer from day one breaks ops; the realistic order is adding when you run short.

The next article covers network (VPC, subnets, CIDR design).

Back to series TOC -> ‘Architecture Crash Course for the Generative-AI Era’: How to Read This Book

I hope you’ll read the next article as well.

📚 Series: Architecture Crash Course for the Generative-AI Era (11/89)