Specialized Stores

The right store for workloads that punish a general-purpose database: time series, analytics, graphs, blobs, and geospatial.

Time series Columnar / OLAP Graph Blob storage Geospatial
๐Ÿ—ƒ

When General-Purpose Isn't Enough

A relational database is a great default and a bad fit for a handful of workloads that have a distinctive access shape. Each store below exists because one pattern โ€” append-only time data, wide analytical scans, deep relationship traversal, huge binary payloads, or 2D proximity โ€” punishes a general-purpose engine. The interview skill is hearing the tell in the question and naming the right store.

๐Ÿ“ˆ

Time Series

Metrics, sensor readings, and events share a shape: massive append-only writes, always stamped with time, almost always queried by time range. Time-series stores (InfluxDB, TimescaleDB, Prometheus) exploit that. They partition by time window so recent data is hot and old data ages out, compress hard with delta encoding (store the difference between consecutive points, which are usually small), and downsample old data into coarser buckets you keep at lower resolution.

๐Ÿ’ก
The tell: "per-second metrics," "sensor data," "monitor over time," retention tiers. When the write rate is enormous and every query has a time range, that's a time-series store, not a table with a timestamp column (Telemetry).
๐Ÿ“Š

Columnar / OLAP

The real split is OLTP vs OLAP. Operational databases (OLTP) read and write whole rows โ€” grab one order, update one user. Analytics (OLAP) scan one or two columns across millions of rows โ€” "average price over all sales this year." Row storage forces analytics to read every column just to touch one. Columnar storage lays each column out contiguously, so a scan reads only what it needs and compresses beautifully because a column holds similar values.

  ROW STORE (OLTP)                      COLUMN STORE (OLAP)
  [id,name,price][id,name,price]โ€ฆ       [id,id,idโ€ฆ][name,nameโ€ฆ][price,priceโ€ฆ]
   read one row = one seek               read one column = one contiguous scan
   great for "get order 42"              great for "SUM(price) over 10M rows"
   analytics reads all columns           reads only the columns queried,
   just to touch price                   compresses similar values hard

Keep the two apart. Run analytics against your operational database and heavy scans lock up the store users depend on. The standard move is a separate warehouse โ€” BigQuery, Redshift, ClickHouse โ€” fed from the operational DB, so analysts scan columns without touching production (Batch & Stream).

๐Ÿ•ธ

Graph

Relational joins get exponentially expensive as you traverse deeper. "Friends of friends of friends" is three self-joins on a huge table โ€” brutal. A graph database (Neo4j, Neptune) stores nodes and edges so that following a relationship is a direct pointer hop, not a join. Adjacency is stored locally, so traversal cost scales with the answer size, not the table size.

โš ๏ธ
Don't reach for a graph database just because your data "has relationships" โ€” all data does. It earns its place only when deep, variable-depth traversal is the core workload: social graphs, fraud rings, recommendation paths. For a friends list one join deep, a relational table is simpler and faster. Most of the time, a graph DB is overkill (Tradeoffs).
๐Ÿชฃ

Blob / Object Storage

Object storage (S3 and its kin) is built for large binary payloads: a flat namespace of keys to objects, accessed over HTTP, with ~11 nines of durability and effectively unlimited scale. No filesystem semantics โ€” no partial in-place edits, no directories, just get/put whole objects. It's cheap, durable, and not a database.

  THE STANDARD PATTERN: split metadata from payload

  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
  โ”‚  Database     โ”‚ id โ”€โ”€โ–ถ โ”‚  Object storage (S3)          โ”‚
  โ”‚  metadata:    โ”‚        โ”‚  the actual bytes:            โ”‚
  โ”‚  owner, name, โ”‚        โ”‚  video.mp4, photo.jpg, backup โ”‚
  โ”‚  size, s3_key โ”‚        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜         payload never passes through your app servers

  UPLOAD: client gets a PRESIGNED URL, uploads DIRECTLY to S3.
  DOWNLOAD: same โ€” client pulls straight from S3 (or a CDN in front).
  LARGE FILES: multipart upload โ€” split into parts, upload in parallel, resume.

The load-bearing pattern across half the case studies: store searchable metadata in a database and the payload bytes in object storage, linked by a key. Presigned URLs grant time-limited permission so clients upload and download directly to storage, bypassing your servers entirely โ€” your app never proxies gigabytes. Multipart upload splits large files into parallel, resumable parts (Video Streaming).

๐Ÿ“

Geospatial Indexing

A B-tree indexes one dimension. "Find drivers within 2km" is two-dimensional โ€” a B-tree on latitude and one on longitude can't answer it efficiently, because a nearby point can be far in either coordinate alone. Geospatial indexes map 2D space onto a 1D orderable key so proximity becomes a range scan.

Geohash prefix = proximity

Recursively divide the map into a grid, encoding each cell as a string. Nearby points share a prefix, so a prefix match finds neighbors, and it indexes as plain text. The catch: two points can be adjacent on the map but sit across a cell boundary with different prefixes โ€” so you check neighboring cells too.

Quadtree adaptive density

Recursively split space into four quadrants, but only subdivide where points are dense. Dense cities get fine cells, empty ocean stays coarse. Adapts to uneven distribution better than a fixed grid, at the cost of a tree to maintain.

๐Ÿ’ก
The tell: "nearby," "within X km," "closest." Name geohash or quadtree, mention the cell-boundary neighbor check, and note the modern libraries โ€” Google's S2 and Uber's H3 โ€” plus backing options like Redis GEO or PostGIS. The Ride Sharing question is built on this (Ride Sharing).
๐Ÿ“‹

Quick Reference

StoreWorkload shapeToolsThe tell
Time seriesAppend-only, time-range queriesInfluxDB, Timescale, Prometheus"per-second metrics," "sensor data"
Columnar / OLAPScan few columns over many rowsBigQuery, Redshift, ClickHouse"analytics," "aggregate over history"
GraphDeep relationship traversalNeo4j, Neptune"friends of friends," "fraud ring"
Blob / objectLarge binary payloadsS3, GCS, Azure Blob"images," "video," "file upload"
Geospatial2D nearest-neighborRedis GEO, PostGIS, S2, H3"nearby," "within X km," "closest"
โ„น๏ธ
The one-liners to keep ready. Reach past the general-purpose DB only when the access shape demands it. Time series for append-heavy time data, columnar for analytical scans (kept off the operational DB), graph only when traversal is the workload, object storage for payloads with the metadata split, geospatial indexes for proximity. Hear the tell, name the store, move on.