Articles

OLTP vs OLAP: Two Very Different Ways to Query Data

OLTP systems handle many small, fast transactions like orders and logins; OLAP systems run large analytical queries across historical data for reporting.

The Lycoris Team The Lycoris Team · · 4 min read
Abstract illustration representing database systems

OLTP (online transaction processing) and OLAP (online analytical processing) describe two fundamentally different database workloads: OLTP handles many small, fast read-write transactions — placing an order, updating a user’s profile, logging in — while OLAP handles large, read-heavy analytical queries that scan and aggregate historical data for reporting and business intelligence. They’re optimized for opposite access patterns, which is why most companies of any size end up running both, backed by different storage engines entirely.

What OLTP optimizes for

An OLTP system is built to process a high volume of short transactions concurrently, each touching a small number of rows: insert one order, update one inventory count, read one user’s session. The defining requirement is correctness under concurrency — many transactions happening at once must not corrupt each other’s data — which is why OLTP databases are built around strict ACID guarantees: atomicity, consistency, isolation, and durability for every transaction.

The storage layout reflects this. OLTP databases are typically row-oriented — all the columns for a single row are stored together on disk — because a typical query reads or writes one whole row at a time (fetch this user, update this order). Database indexing on primary and foreign keys makes those single-row lookups fast, and normalization keeps data consistent by avoiding redundant copies that could drift out of sync during concurrent writes.

Examples: PostgreSQL and MySQL running an e-commerce checkout flow, a banking ledger, a SaaS application’s core database.

What OLAP optimizes for

An OLAP system is built for the opposite pattern: relatively few queries, but each one scans and aggregates across millions or billions of rows — total revenue by region last quarter, average session length by user cohort, month-over-month churn. Individual-row correctness under heavy concurrent writes isn’t the priority here; query throughput over huge volumes of mostly historical, rarely-updated data is.

This is why OLAP systems are usually column-oriented instead of row-oriented: since an aggregation query typically needs one or two columns (revenue, region) across every row rather than every column of a few rows, storing each column contiguously on disk lets the engine skip reading columns it doesn’t need and compress similar values efficiently. OLAP workloads also tolerate — and often prefer — some denormalization, trading storage space for fewer joins during a large aggregation.

Examples: a data warehouse aggregating sales across every store, a dashboard computing weekly active users, a BI tool building a revenue report.

Side by side

OLTPOLAP
Typical queryRead/write one or few rowsAggregate across millions of rows
Storage layoutRow-orientedColumn-oriented
Data freshnessReal-time, current stateOften batch-loaded, historical
SchemaNormalizedOften denormalized (star/snowflake schema)
ConcurrencyMany small concurrent transactionsFew large, long-running queries
Consistency modelStrict ACIDEventual consistency often acceptable
Example workloadCheckout, login, inventory updateQuarterly revenue report, cohort analysis

Why one database rarely does both well

Running heavy analytical queries directly against a production OLTP database is a well-known way to cause an outage: a multi-minute aggregation query holding locks or consuming I/O can starve the small, fast transactions the OLTP system exists to serve quickly. That’s the practical reason companies separate the two — an OLTP database (say, PostgreSQL) handles the live application, and data is periodically extracted, transformed, and loaded (ETL, or its streaming cousin ELT) into a separate OLAP-oriented warehouse built for exactly the analytical query patterns that would otherwise compete with production traffic. This separation is also why read replicas are common even for OLTP-only setups — running reporting queries against a replica keeps them from contending with the primary’s write path.

The underlying trade the CAP theorem describes shows up here too, in a practical rather than strictly formal sense: OLTP systems generally accept more coordination overhead in exchange for strong consistency on every write, while OLAP systems, working from data that’s already settled, can prioritize query throughput over having the absolute latest write reflected instantly.

Where the line blurs

The distinction isn’t always this crisp in practice. Some newer engines describe themselves as HTAP (hybrid transactional/analytical processing), attempting to serve both patterns from one system, usually by keeping a row-oriented store for writes and maintaining a column-oriented replica for analytics under the hood. SQL window functions — running totals, rankings, moving averages — are a good example of a feature that started as an OLAP-flavored tool but is now common in OLTP databases too, since even transactional applications sometimes need lightweight analytics without shipping data to a separate warehouse. And sharding a large OLTP database for write scalability is a different problem from partitioning an OLAP warehouse for query parallelism, even though both get called “sharding” colloquially.

The takeaway

OLTP and OLAP aren’t different products so much as different answers to “what does a typical query look like here.” OLTP is many small, fast, concurrent transactions on current data, best served by a row-oriented, strictly consistent database. OLAP is fewer, larger aggregation queries over historical data, best served by a column-oriented store optimized for scanning. Most real systems need both, which is why production traffic and analytical reporting are usually kept on separate infrastructure rather than forced through the same database.

The Lycoris Team The Lycoris Team · · 5 min read

What Is a Database Trigger?

A database trigger is a procedure that runs automatically on an insert, update, or delete — enforcing rules the application layer can't guarantee.

#Databases #SQL #Backend
The Lycoris Team The Lycoris Team · · 4 min read

Primary Key vs Foreign Key vs Unique Constraint

Primary keys identify a row, foreign keys link one table to another, and unique constraints just prevent duplicates. How the three differ in SQL.

#Databases #SQL #Backend