EXECUTION & PERFORMANCEPySpark

Caching, Persistence & Checkpointing

Distributed data processing with Spark — pick a topic on the left and its full breakdown loads here: the execution model, worked jobs and diagrams, performance and shuffle behavior, and the habits that keep Spark jobs fast, correct, and affordable.

18 min readTopics chapter readerLevel · Performance
01 · Orientation

What You'll Master Here

Without caching, every action replays the full recipe from raw ingredients. cache() saves the cooked dish so the next person just reheats it. Worth it only if the dish is reused.

4 min · Topic 1 of 4

Because transformations are lazy (Chapter 5), Spark recomputes a DataFrame from scratch every time you trigger an action on it. If you reuse the same DataFrame several times, that is wasteful, you recompute the whole lineage each time. Caching fixes this: it stores the computed result so later actions reuse it instead of recomputing.

This chapter covers cache() and persist(), the storage levels (memory, disk, serialized), when caching genuinely helps versus when it hurts (it is not free, it consumes memory), and checkpointing, a different tool that truncates a long lineage by writing it to reliable storage.

With a diagram of recompute-vs-cache and a worked example of caching a reused DataFrame. The key judgment: cache only what you reuse, and remember to unpersist.

Core mental model

Without caching, every action replays the full recipe from raw ingredients. cache() saves the cooked dish so the next person just reheats it. Worth it only if the dish is reused.

Why it matters

Caching the right DataFrame can turn a job that recomputes an expensive pipeline five times into one that computes it once. Caching the wrong thing wastes memory and can slow the job down, knowing the difference matters.

cache()
Marks a DataFrame to be stored after first computation (memory by default).
persist(level)
Like cache but with an explicit storage level (memory/disk/serialized).
storage level
Where and how cached data is kept: MEMORY_ONLY, MEMORY_AND_DISK, etc.
checkpointing
Writing a DataFrame to reliable storage to cut (truncate) its lineage.
Common mistake

Caching a DataFrame that is used only once. You pay the memory cost (and eviction of other data) for zero reuse benefit, a net loss.

Better habit

Cache only DataFrames you reuse across multiple actions.

Pick the storage level deliberately; the default is MEMORY_AND_DISK for DataFrames.

unpersist() when done to free memory for the rest of the job.

The big idea

Laziness means recompute-by-default. Caching trades memory for avoided recomputation, worth it precisely when a DataFrame is reused. Checkpointing instead trades a write for a shorter, safer lineage.

Remember this

Cache a DataFrame when you reuse it across actions, to avoid recomputing its lineage each time. Choose the storage level deliberately, unpersist when done, and use checkpointing to truncate overly long lineages.

Practice2 prompts
  1. Why does Spark recompute a DataFrame on every action by default?
  2. When is caching a net loss rather than a win?