Matías Fernández / System Design ALGORITHMS · FIELD NOTE 03

System Design Field Notes Data Structures

DATA STRUCTURES · COMPLEXITY · TRADE-OFFS

Big O is
not a speed.

It describes how cost grows as input grows. The fastest structure is therefore not a universal winner: it is the one whose cheap operations match your hot path, whose guarantees match your risk, and whose memory layout fits the machine.

GROWTH, NOT STOPWATCH TIMEn → ∞

same Big O same runtime

PUBLISHED
AUG 13 2026
READING
~14 min
SCOPE
Core structures
GOAL
Choose by workload

01 / READ THE NOTATION

One letter hides
three different promises.

Complexity claims are only useful when you know which case they describe and what the input variable represents.

WORST CASE

O( )

An upper bound. The operation will not grow faster than this class beyond some input size. It is the safety-oriented view.

TIGHT BOUND

Θ( )

The actual growth class is bounded above and below. Saying array indexing is Θ(1) is more precise than merely O(1).

AMORTIZED

Σ / m

An expensive operation is spread across a sequence. Dynamic-array append is usually constant on average over many appends, although one resize is O(n).

Average case assumes a distribution of inputs. Hash-table lookup is average Θ(1), but collisions can produce O(n) worst-case behavior. That distinction matters for untrusted keys and latency-sensitive systems.

Also name the variable. A trie lookup is O(L), where L is key length. Graph traversal is O(V + E), not simply O(n). Good analysis defines the unit before comparing curves.

THE FIRST RULE

Drop constants in the model. Measure them in the system.

02 / THE COMPARISON TABLE

Complexity is a
cost profile.

These are common implementation guarantees. Language runtimes can differ, so treat the table as a map and verify the concrete container you use.

STRUCTUREACCESS / PEEKSEARCHINSERTDELETEBEST FIT
Dynamic arrayΘ(1)O(n)Amortized Θ(1)O(n)Fast indexed reads and iteration
Linked listO(n)O(n)Θ(1)*Θ(1)*Known-node insertion or removal
Hash tableAverage Θ(1)Average Θ(1)Average Θ(1)Exact-key lookup
Balanced BSTMin/max O(log n)O(log n)O(log n)O(log n)Ordered keys and range queries
Binary heapPeek Θ(1)O(n)O(log n)Root O(log n)Repeated min/max extraction
Stack / queuePeek Θ(1)Θ(1)Θ(1)LIFO / FIFO workflows
TrieO(L)O(L)O(L)Prefix search over strings
* THE POINTER TAX

Linked-list insert and delete are Θ(1) only when you already have the relevant node (and, for deletion, the required predecessor or a doubly linked list). Finding that node is O(n). This footnote changes many interview answers—and many production designs.

03 / WHERE EACH ONE WINS

No champion.
Only a better fit.

A structure wins when it makes the dominant operation cheap without charging unacceptable costs elsewhere.

01

Dynamic array

USE WHEN
Indexed reads, compact storage, and full scans.
WINS
Better locality than linked nodes; often faster in practice even when both operations are O(n).
PAYS WITH
Middle insertion shifts elements; growth occasionally copies the backing storage.
02

Hash table

USE WHEN
Membership, deduplication, counters, caches, and exact-key joins.
WINS
Average O(1) lookup beats a tree or array when ordering is irrelevant.
PAYS WITH
No sorted traversal; collisions, resizing, and hash quality affect latency and memory.
03

Balanced tree

USE WHEN
Sorted iteration, predecessor/successor, and range queries.
WINS
O(log n) operations with useful order—something a hash table cannot provide.
PAYS WITH
More pointer chasing and slower exact lookup constants than a good hash table.
04

Binary heap

USE WHEN
Schedulers, top-k queries, and priority queues.
WINS
O(1) peek and O(log n) push/pop without paying to keep every element fully sorted.
PAYS WITH
Finding an arbitrary item is O(n); it is not a general-purpose search structure.
05

Stack / queue

USE WHEN
Undo, parsing, BFS, work buffers, and streaming pipelines.
WINS
O(1) operations encode the required order directly and keep the API constrained.
PAYS WITH
They intentionally do not optimize arbitrary access or search.
06

Trie

USE WHEN
Autocomplete, routing tables, and prefix dictionaries.
WINS
O(L) depends on key length, not the number of stored keys.
PAYS WITH
High memory overhead; a sorted array can be smaller and cache-friendlier.

04 / START FROM THE QUERY

Turn requirements
into operations.

“Store some items” is not a workload. The question you ask repeatedly is what should shape the structure.

  1. 01

    Need item #i

    Dynamic array. Direct addressing gives Θ(1) access and contiguous memory.

  2. 02

    Need exact key x

    Hash table. Average Θ(1) membership; use a set when values are unnecessary.

  3. 03

    Need keys between a and b

    Balanced tree. Ordering makes range traversal O(log n + k) for k results.

  4. 04

    Need the next highest priority

    Binary heap. Peek in O(1), then remove in O(log n).

  5. 05

    Need all keys beginning with pre

    Trie. Walk the prefix in O(L), then enumerate its subtree.

  6. 06

    Need FIFO or LIFO only

    Queue or stack. The restricted interface makes both end operations O(1).

  7. 07

    Need to scan everything

    Dynamic array. Contiguous layout usually wins on cache locality and overhead.

COMPOSITION BEATS LOYALTYReal systems combine structures.

An LRU cache commonly uses a hash table for O(1) key lookup plus a doubly linked list for O(1) recency updates. A database index may use a B-tree while its buffer manager uses a hash table and queues. Choose per operation, not once per application.

05 / BIG O MEETS HARDWARE

Asymptotics predict.
Machines decide.

For finite data, representation and access pattern can outweigh the headline complexity.

01

Cache locality

WHY

Arrays place neighboring values together. CPUs fetch cache lines, so sequential scans can beat pointer-heavy structures by a wide margin.

RESULT

An O(n) array scan may outperform theoretically better lookup at small or moderate n.

02

Memory overhead

WHY

Pointers, empty hash buckets, tree nodes, and trie edges consume memory beyond the stored values.

RESULT

A compact sorted array can be the better read-mostly index despite O(log n) lookup.

03

Input distribution

WHY

Hash collisions, skewed trees, hot keys, and repeated prefixes change observed behavior.

RESULT

Benchmark representative data, including adversarial or pathological cases when relevant.

04

Mutation rate

WHY

A structure optimized for reads may pay heavily to preserve order or rebuild storage on writes.

RESULT

Include the read/write ratio, batching, concurrency, and allocation cost in the decision.

06 / A PRACTICAL METHOD

Choose, measure,
then defend.

The simplest structure that meets the actual access pattern is usually the best starting point.

  1. 01

    List the operations

    Write down reads, writes, deletes, scans, ranges, prefix queries, and min/max extraction.

  2. 02

    Weight the hot path

    A million lookups and ten insertions should not influence the choice equally.

  3. 03

    Require the right guarantee

    Separate average, amortized, and worst case; decide which latency tail can hurt the product.

  4. 04

    Estimate scale and memory

    Use realistic n, key length, object size, growth, and concurrency—not an abstract infinite input.

  5. 05

    Prefer the standard library

    Its containers are tested and optimized. Introduce a custom structure only with evidence.

  6. 06

    Benchmark the workload

    Measure latency distribution, memory, allocations, and throughput with production-shaped data.

DESIGN REVIEW

Before choosing
the container.

  • 01What operations dominate: lookup, traversal, insertion, deletion, range, or min/max?
  • 02Do I need ordering, stable iteration, prefixes, or only exact keys?
  • 03Am I comparing average, amortized, or worst-case guarantees?
  • 04What are n and L in this workload, and how large will they become?
  • 05Does memory layout or allocation overhead matter more than asymptotic growth?
  • 06Can the standard library structure express this workload safely?
  • 07Did I benchmark with production-like size, distribution, and access patterns?

THE DECISION IN ONE LINE

Optimize the operation,
not the name.

Big O narrows the search. Workload shape, guarantees, memory behavior, and measurement finish the decision. Start with what the system does most, then make that path deliberately cheap.

07 / SOURCES & NEXT STEPS

Keep
exploring.

  1. 01Algorithms, 4th EditionData structures, analysis, and implementations · Princeton ↗
  2. 02Introduction to AlgorithmsOpen course materials and lectures · MIT OpenCourseWare ↗
  3. 03Python Data StructuresConcrete standard-library containers · Python Docs ↗