Advanced16 min

Data Architecture

Pick the right store for each job — and own the data per service.

By the end of this lesson, match storage engines to access patterns and apply database-per-service.

How deep?
How the pieces actually move.

There is no universal database. Data architecture is the discipline of matching each workload to a store whose data model and guarantees fit it: relational for transactions and joins, document for flexible aggregates, key-value for speed, columnar for analytics, search for full-text, vector for similarity, time-series for metrics. Using several deliberately is polyglot persistence.

First, the whole system

First, see the whole system. Then we’ll open it up.

Right tool per access pattern

Right tool per access pattern

  1. Transactions and joins go to relational stores; hot lookups to key-value; analytics to columnar/OLAP; semantic search to a vector DB; full-text to a search index.
flowchart TB
  oltp[Transactions/joins] --> rel[(Relational)]
  fast[Hot key lookups] --> kv[(Key-value)]
  analytics[Aggregations] --> col[(Columnar / OLAP)]
  similarity[Semantic search] --> vec[(Vector DB)]
  text[Full-text] --> search[(Search index)]

In microservices, each service owns its data (database-per-service) so it can evolve and scale independently — no shared database backdoor. That autonomy is why cross-service consistency needs sagas, outbox, and events rather than one big transaction. Scaling a single store adds replication (read scale, availability) and sharding/partitioning (write scale), each with its own consistency cost.

Operational complexity

Polyglot, per-service data maximizes fit and autonomy but multiplies the systems you operate, back up, and keep consistent. A single shared database is simpler to run but becomes a coupling point and a scaling bottleneck.

Abstraction leak

This is where the abstraction starts leaking.

Sharding hides behind a clean 'it scales horizontally' story until a cross-shard query or transaction appears. Then the abstraction leaks hard: joins span nodes, hot shards emerge, and rebalancing becomes an operation you plan for weeks.

Why does database-per-service push you toward sagas and events?

Because no service can reach into another's database, cross-service changes can't use one transaction; they must be coordinated with events, outbox, and compensating sagas.

Distributing data across many stores makes failures harder to diagnose. How do you observe and keep a sprawling system reliable?

Next: Observability & Reliability →