0Pricing
SQL Academy · Lesson

OLTP vs OLAP

Transactional vs analytical databases.

OLTP vs OLAP is a free SQL Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the SQL Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

What Are OLTP and OLAP?

Databases are not one-size-fits-all. Two fundamentally different workloads have shaped how we design and operate databases: OLTP (Online Transaction Processing) and OLAP (Online Analytical Processing).

Understanding the difference is essential for any data professional. The right choice between OLTP and OLAP determines query speed, storage cost, and the overall architecture of your data system.

OLTP: Built for Transactions

OLTP systems handle a high volume of short, fast operations — inserts, updates, and deletes that reflect real-time business events. Examples include placing an order, processing a payment, or updating a customer record.

The key properties of OLTP are: low latency per operation, high concurrency, and strong consistency. Every transaction must be ACID-compliant to protect data integrity.

-- OLTP example: inserting a new order
INSERT INTO orders (customer_id, product_id, quantity, order_date)
VALUES (1042, 88, 3, CURRENT_DATE);

-- Immediately update inventory
UPDATE inventory
SET stock = stock - 3
WHERE product_id = 88;

OLAP: Built for Analysis

OLAP systems are optimized for complex queries that scan large amounts of historical data to reveal trends, patterns, and summaries. Business analysts and data scientists use OLAP to answer questions like: 'What were our total sales by region last quarter?'

OLAP queries often aggregate millions of rows and involve multiple joins across fact and dimension tables. Speed of individual writes is secondary; read throughput and query flexibility are what matter.

-- OLAP example: total sales by region for Q1 2024
SELECT
    d.region,
    SUM(f.sales_amount) AS total_sales,
    COUNT(f.order_id)   AS order_count
FROM fact_sales f
JOIN dim_date   dd ON f.date_key   = dd.date_key
JOIN dim_store  d  ON f.store_key  = d.store_key
WHERE dd.year = 2024
  AND dd.quarter = 1
GROUP BY d.region
ORDER BY total_sales DESC;

Comparing the Two Side by Side

The easiest way to remember the distinction is to think about who uses each system and how they use it:

  • OLTP: used by application backends; thousands of concurrent users; each query touches a few rows.
  • OLAP: used by analysts and reporting tools; fewer concurrent queries but each scans millions of rows.

These contrasting access patterns lead to very different schema designs, indexing strategies, and even hardware choices.

-- OLTP: lookup a single customer's latest order (row-level access)
SELECT o.order_id, o.order_date, o.total_amount
FROM orders o
WHERE o.customer_id = 1042
ORDER BY o.order_date DESC
LIMIT 1;

-- OLAP: monthly revenue trend over the past year (aggregate scan)
SELECT
    DATE_TRUNC('month', order_date) AS month,
    SUM(total_amount)               AS revenue
FROM orders
WHERE order_date >= CURRENT_DATE - INTERVAL '12 months'
GROUP BY 1
ORDER BY 1;

Schema Design: Normalized vs Denormalized

OLTP databases favor normalized schemas (3NF or higher) to eliminate redundancy and make writes efficient. Each entity lives in its own table, reducing the data touched per transaction.

OLAP databases favor denormalized schemas — especially star and snowflake schemas — where data is pre-joined and redundant. This eliminates expensive joins at query time and allows columnar storage engines to scan data faster.

-- Normalized OLTP design (3NF)
CREATE TABLE customers (
    customer_id SERIAL PRIMARY KEY,
    name        VARCHAR(100),
    email       VARCHAR(150) UNIQUE
);

CREATE TABLE orders (
    order_id    SERIAL PRIMARY KEY,
    customer_id INT REFERENCES customers(customer_id),
    order_date  DATE,
    total       NUMERIC(10,2)
);

-- Denormalized OLAP fact table (star schema)
CREATE TABLE fact_sales (
    sale_id      BIGINT PRIMARY KEY,
    customer_key INT,
    date_key     INT,
    product_key  INT,
    region       VARCHAR(50),
    category     VARCHAR(50),
    amount       NUMERIC(12,2)
);

Indexing Strategies Differ

OLTP systems rely heavily on B-tree indexes on primary keys and foreign keys to enable fast single-row lookups and efficient joins within a transaction.

OLAP systems benefit from bitmap indexes, columnar storage, and partitioning. Scanning an entire column (e.g., all sales amounts) is far more efficient when data is stored column-by-column rather than row-by-row.

-- OLTP: B-tree index for fast order lookup by customer
CREATE INDEX idx_orders_customer
    ON orders (customer_id);

-- OLTP: compound index for range queries
CREATE INDEX idx_orders_date_customer
    ON orders (order_date, customer_id);

-- OLAP: partition fact table by year to prune scan
CREATE TABLE fact_sales_2024
    PARTITION OF fact_sales
    FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');

Concurrency and Locking

OLTP systems must handle thousands of concurrent writes without conflicts. Databases use row-level locking and MVCC (Multi-Version Concurrency Control) so that readers never block writers and vice versa.

OLAP queries are predominantly read-only. Locking is rarely an issue, but long-running scans can consume significant CPU and I/O. Most data warehouses run OLAP on a separate system populated by batch ETL or CDC (Change Data Capture) from the OLTP source.

-- OLTP: explicit transaction with row-level lock
BEGIN;

SELECT balance
FROM accounts
WHERE account_id = 7
FOR UPDATE;

UPDATE accounts
SET balance = balance - 200
WHERE account_id = 7;

COMMIT;

ETL: Bridging OLTP and OLAP

Because OLTP and OLAP have incompatible designs, organizations run ETL (Extract, Transform, Load) pipelines to copy and reshape data from the transactional database into the analytical warehouse on a schedule (nightly, hourly, or near-real-time).

The ETL process transforms normalized OLTP rows into denormalized fact and dimension records, applying business logic along the way (e.g., currency conversion, customer segmentation).

-- Simplified ETL INSERT from OLTP orders into OLAP fact table
INSERT INTO fact_sales (
    customer_key,
    date_key,
    product_key,
    amount
)
SELECT
    dc.customer_key,
    dd.date_key,
    dp.product_key,
    o.total_amount
FROM orders o
JOIN dim_customer dc ON dc.source_customer_id = o.customer_id
JOIN dim_date     dd ON dd.calendar_date       = o.order_date
JOIN dim_product  dp ON dp.source_product_id   = o.product_id
WHERE o.order_date = CURRENT_DATE - INTERVAL '1 day'
  AND o.order_id NOT IN (SELECT source_order_id FROM fact_sales);

Typical OLAP Query Patterns

OLAP queries almost always involve aggregations (SUM, COUNT, AVG), grouping across multiple dimensions, and filtering by date ranges or categories. These are the building blocks of dashboards and business reports.

Window functions are especially powerful in OLAP workloads — they let you compare each period's figures against the previous period without a self-join.

-- Year-over-year revenue comparison using a window function
SELECT
    dd.year,
    dd.quarter,
    SUM(f.amount)                                          AS revenue,
    LAG(SUM(f.amount)) OVER (PARTITION BY dd.quarter
                             ORDER BY dd.year)             AS prev_year_revenue,
    ROUND(
        100.0 * (SUM(f.amount) -
                 LAG(SUM(f.amount)) OVER (PARTITION BY dd.quarter
                                         ORDER BY dd.year))
        / NULLIF(LAG(SUM(f.amount)) OVER (PARTITION BY dd.quarter
                                          ORDER BY dd.year), 0)
    , 2)                                                   AS yoy_pct_change
FROM fact_sales f
JOIN dim_date dd ON f.date_key = dd.date_key
GROUP BY dd.year, dd.quarter
ORDER BY dd.quarter, dd.year;

HTAP: Blurring the Lines

Modern systems like TiDB, SingleStore, and PostgreSQL + columnar extensions implement HTAP (Hybrid Transactional/Analytical Processing). They aim to handle both workloads in a single engine, avoiding the operational complexity of maintaining separate OLTP and OLAP systems.

HTAP achieves this by storing data in two formats simultaneously: a row store for transactional writes and a column store for analytical reads, kept in sync automatically.

-- PostgreSQL with cstore_fdw (columnar extension) example
-- Analytical table stored in columnar format
CREATE FOREIGN TABLE fact_sales_columnar (
    date_key     INT,
    product_key  INT,
    region       VARCHAR(50),
    amount       NUMERIC(12,2)
)
SERVER cstore_server
OPTIONS (filename '/data/fact_sales_columnar');

-- Regular OLTP table remains row-based
-- Both can be queried in the same SQL statement
SELECT f.region, SUM(f.amount)
FROM fact_sales_columnar f
GROUP BY f.region;

Choosing the Right System

The decision between OLTP and OLAP (or HTAP) comes down to your primary workload:

  • If you are building an application that records events in real time — use an OLTP database (PostgreSQL, MySQL, SQL Server).
  • If you are building a reporting layer over historical data — use an OLAP warehouse (BigQuery, Redshift, Snowflake, ClickHouse).
  • If you need both and want operational simplicity — evaluate HTAP options.

Many production architectures use both: an OLTP database as the system of record and a separate data warehouse for analytics, connected by an ETL pipeline.

-- Quick diagnostic: check table access pattern
-- High seq_scan relative to idx_scan = analytical (OLAP-like) load
SELECT
    relname              AS table_name,
    seq_scan,
    idx_scan,
    n_live_tup           AS live_rows
FROM pg_stat_user_tables
ORDER BY seq_scan DESC
LIMIT 10;

Knowledge Check

Test your understanding of the key differences between OLTP and OLAP systems.

Lesson Recap

OLTP vs OLAP — key takeaways:

  • OLTP handles real-time transactional workloads: fast, concurrent, row-level writes with ACID guarantees.
  • OLAP handles analytical workloads: complex aggregations over large historical datasets, using denormalized schemas.
  • Schema design follows the workload — normalized (3NF) for OLTP, star/snowflake for OLAP.
  • ETL pipelines bridge the two systems, loading transformed OLTP data into the analytical warehouse.
  • HTAP systems attempt to serve both workloads from a single engine using dual row/column storage.

Choosing the right architecture from the start prevents painful migrations later and ensures your queries run at the speed your users expect.

Frequently asked questions

Is the “OLTP vs OLAP” lesson free?

Yes — the full text of “OLTP vs OLAP” is free to read here on the web, and the SQL Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the SQL Academy course, upgrade to CoddyKit PRO.

What will I learn in “OLTP vs OLAP”?

Transactional vs analytical databases. You practise SQL Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start SQL Academy?

No prior experience is required. SQL Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “OLTP vs OLAP” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this SQL Academy lesson?

Yes. Every SQL Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. OLTP vs OLAP
  2. Fact and Dimension Tables
  3. Star and Snowflake Schemas
  4. Writing Analytical Queries
← Back to SQL Academy