swecrets

Vocabulary of the OLAP World

Foundations — Rung 19 min read

Learning Objectives

  • Define and correctly use throughput, latency, ingestion, cardinality, and query engine in the context of analytics databases
  • Explain why throughput and latency are often in tension rather than both maximized together
  • Predict whether a described column has low or high cardinality

Why This Matters

Tell your team a system needs "low latency" when you actually mean "high throughput," and you'll spec out the wrong thing entirely — a system tuned to answer one query in two milliseconds is a genuinely different design than one tuned to answer ten million queries per second in aggregate. Get "cardinality" wrong and you'll reach for a technique that quietly does nothing, or one that blows up storage for no benefit. This vocabulary isn't decoration on top of the last four lessons — it's the language every design conversation for the rest of this course will be conducted in, and precision here is what prevents expensive misunderstandings later.

Analogy

Picture a busy coffee shop during the morning rush.

New orders arrive at the register constantly — someone's always walking up. That arriving stream, moment to moment, is one thing worth naming on its own.

The shop as a whole completes some number of drinks per hour — maybe 300 on a good morning. That's a different thing worth naming: a rate, measured across the whole operation.

Then there's you, personally, standing at the counter: how long does it take from the moment you order to the moment your one drink is in your hand? That's a third thing — and notice it's not the same question as "how many drinks per hour." The shop could be completing 300 drinks an hour while your own latte still takes four minutes to reach you.

Now look at today's stack of order tickets. The "size" field on those tickets only ever says small, medium, or large — three possible values, no matter how many hundreds of tickets you have. The "customer's exact name" field, on the other hand, is different on nearly every single ticket. Same stack of tickets, two fields, wildly different numbers of distinct values.

And at the end of the day, if someone asks the shift manager "how many oat-milk drinks did we sell between 2 and 4pm," someone has to actually go dig through the tickets and produce that number. That process — taking a question and turning it into an answer by working through the accumulated data — is the last piece of vocabulary this lesson needs.

Five terms, one shop

Ingestion is the arriving stream of orders — the process of new data entering the system, moment to moment. In an analytics database, ingestion is what happens every time a new row lands: an event, a log line, a click.

Throughput is the shop's total completed-drinks-per-hour — a rate measured across the whole system, not any one order. In a database, throughput usually means something like rows ingested per second, or queries answered per second, in aggregate.

Latency is how long your one drink takes, start to finish. In a database, latency is almost always about a single operation: how long did this query take to return, how long did this row take to become queryable.

Throughput and latency sound related — surely a "fast" system is fast on both? They're not the same axis, and they're frequently in tension. A system can process an enormous number of drinks per hour by batching: collecting fifty orders, making them all at once, handing out the batch every ten minutes. Throughput goes up. But now any individual customer's latency — the time from their order to their drink in hand — got much worse, because they're waiting for the whole batch. The reverse trade happens too: a shop that makes exactly one drink at a time, immediately, the instant it's ordered, gives every customer excellent latency, but can't complete nearly as many drinks per hour as the batching shop can.

Cardinality describes one field across a whole stack of tickets: how many distinct values show up in it. "Drink size" has low cardinality — only three possible values, no matter how many tickets pile up. "Customer's exact name" has high cardinality — almost as many distinct values as there are tickets. Cardinality isn't a property of the whole ticket stack; it's a property of one specific field within it, and different fields on the same tickets can have wildly different cardinality.

Query engine is the process that answers a question about the accumulated tickets after the fact — "how many oat-milk drinks between 2 and 4pm" — by actually working through the data and producing a number. In a database, the query engine is the machinery that takes a request written in SQL and turns it into an answer, whatever work that requires underneath.

Throughput vs. Latencythroughput: whole flowlatency: one tripCardinalitylowhigh
Throughput vs. latency, and low vs. high cardinality. Two side-by-side cards. The left card, labeled Throughput vs. Latency, contains two small icons: a wide pipe with many small dots flowing through it labeled throughput, next to a stopwatch tracking a single highlighted dot's journey labeled latency, illustrating that one measures the whole flow and the other measures one item's trip through it. The right card, labeled Cardinality, contains two short columns of small squares: the left column's squares are all the same single color, labeled low cardinality, and the right column's squares are each a different color, labeled high cardinality.

A worked example

A real-time OLAP system ingests two million events per second from a fleet of servers — that rate of incoming rows is its ingestion rate. Across the whole system, it answers something like eight thousand dashboard queries per second — that's throughput. Any one of those dashboard queries — say, "what's the error rate for the last hour" — comes back in 200 milliseconds; that single query's response time is its latency.

Two of the columns in this data tell very different stories. The server_id column has about forty thousand distinct values across the whole fleet — high cardinality. The http_status_code column has maybe a dozen distinct values total (200, 404, 500, and a handful of others) — low cardinality. Same rows, two columns, very different cardinality.

And the piece of the system that takes "what's the error rate for the last hour" and turns it into an actual number, by working through the ingested rows and computing the answer, is the query engine.

Common Misconception

"A system with high throughput must also have low latency — they basically measure the same thing, 'how fast is it.'"

They measure genuinely different things, and pushing one up can push the other down. Batching is the clearest example: collect many small operations and process them together, and you can complete far more of them per second in aggregate — throughput goes up. But any individual operation now has to wait for its whole batch to be ready, so its own response time — latency — gets worse, not better. A system can be excellent on one axis and mediocre on the other; "fast" isn't one number, it's at least two.

Predict, Then Verify

For each column, predict: low cardinality or high cardinality?

  1. A day_of_week column.
  2. A user_email column.
  3. An http_status_code column.
  4. An event_timestamp_with_microseconds column.
Reveal the answer →
  1. Low — only seven possible distinct values, no matter how many rows there are.
  2. High — close to as many distinct values as there are users.
  3. Low — a few dozen standard codes at most.
  4. Very high — microsecond-precision timestamps rarely repeat, so nearly every row has its own distinct value.

Summary

Ingestion is the rate at which new data enters a system; throughput is how much work the whole system completes per unit of time; latency is how long any one operation takes, start to finish — and the two aren't the same axis, since batching can raise throughput while worsening latency, or vice versa. Cardinality describes how many distinct values show up in one specific column, not the dataset as a whole, and it varies enormously from column to column on the very same rows. The query engine is the machinery that turns a question into an answer by working through the accumulated data. You now have the vocabulary this whole course will keep reusing — and you can look at a column or a system description and reason correctly about which of these terms actually applies.

Quiz

  1. 1. A system processes 50,000 rows per second in aggregate, but any single row takes 800 milliseconds to become queryable after it's ingested. Which term describes the 50,000-rows-per-second figure, and which describes the 800-millisecond figure?

  2. 2. A team batches incoming orders and processes them in groups of 200 every 30 seconds, instead of one at a time as they arrive. What's the most likely effect on throughput and latency?

  3. 3. A `country_code` column and a `transaction_id` column sit on the same table of a billion rows. What would you expect about their relative cardinality, and why?

  4. 4. What is a query engine responsible for, in the vocabulary this lesson establishes?

  5. 5. A dashboard needs to show "requests per second, broken down by status code, updated every few seconds." Which of this lesson's terms are actually in play, and how?