home
diamond Go Premium
Data Engineering Path  ·  PySpark

RDD - Repartition & Coalesce

In Apache Spark, partitions are the basic unit of parallel processing. The speed and efficiency of your cluster depends directly on how your data is distributed across these partitions.

Sometimes, you need to adjust the number of partitions of an existing RDDeither to increase parallelism or to reduce storage overhead before saving. Spark offers two primary methods for this: repartition() and coalesce().

This guide details the mechanical and performance differences between these two methods, accompanied by illustrative PySpark examples.


The Key Mechanical Differences

Feature repartition(numPartitions) coalesce(numPartitions)
Primary Goal Increase or decrease partition count. Decrease partition count only.
Network Shuffle Forces a full network shuffle of all records. Avoids network shuffle (merges local partitions).
Dependency Type Wide Transformation (High performance overhead). Narrow Transformation (Low performance overhead).
Data Balance Re-distributes data evenly across partitions. Can lead to unevenly sized partitions (data skew).
graph TD
    subgraph RepartitionFlow["repartition() - Full Network Shuffle"]
        direction LR
        P1["Part 1"] --> S1["Shuffle Manager"]
        P2["Part 2"] --> S1
        S1 --> NP1["New Part 1 (Balanced)"]
        S1 --> NP2["New Part 2 (Balanced)"]
        S1 --> NP3["New Part 3 (Balanced)"]
    end

    subgraph CoalesceFlow["coalesce() - Local Merging (No Shuffle)"]
        direction LR
        PP1["Part 1"] --> CP1["New Part 1"]
        PP2["Part 2"] --> CP1
        PP3["Part 3"] --> CP2["New Part 2"]
    end

    style RepartitionFlow fill:#ffebee,stroke:#c62828,stroke-width:2px;
    style CoalesceFlow fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px;

Setting Up Spark Session (For Code Examples)

from pyspark.sql import SparkSession

spark = SparkSession.builder \
    .appName("Day01 Partitioning") \
    .master("local[*]") \
    .getOrCreate()

sc = spark.sparkContext

1. Using repartition(numPartitions)

Use repartition() when you want to increase the number of partitions to scale up your cluster parallelization, or when your data is highly skewed (some partitions are massive, others are empty) and you want to force an even distribution.

Code Example:

# 1. Create a small RDD with 2 partitions
raw_rdd = sc.parallelize([1, 2, 3, 4, 5, 6, 7, 8], numSlices=2)
print("Initial Partitions:", raw_rdd.getNumPartitions()) # 2
print("Initial Layout:", raw_rdd.glom().collect())
# Output: Initial Layout: [[1, 2, 3, 4], [5, 6, 7, 8]]

# 2. Increase partitions to 4 using repartition()
# This triggers a complete network shuffle to distribute elements evenly
repartitioned_rdd = raw_rdd.repartition(4)

print("
--- After Repartition ---")
print("New Partitions count:", repartitioned_rdd.getNumPartitions()) # 4
print("Repartitioned Layout:", repartitioned_rdd.glom().collect())

# Typical Output:
# Repartitioned Layout: [[1, 5], [2, 6], [3, 7], [4, 8]]
# Note: Data has been completely reshuffled into equal-sized blocks!

2. Using coalesce(numPartitions)

Use coalesce() when you want to decrease the number of partitions. Instead of shuffling data across the network, coalesce keeps data on the worker node local disks and simply groups adjacent partitions together.

  • Primary Use Case: When writing results to a database or filesystem. If your RDD has 200 partitions, saving it will generate 200 small part-* files, creating heavy HDFS metadata bloat. Coalescing to 1 or 4 partitions before saving ensures a small, clean file list.

Code Example:

# 1. Create a small RDD with 4 partitions
large_partition_rdd = sc.parallelize([1, 2, 3, 4, 5, 6, 7, 8], numSlices=4)
print("Initial Partitions:", large_partition_rdd.getNumPartitions()) # 4
print("Initial Layout:", large_partition_rdd.glom().collect())
# Output: Initial Layout: [[1, 2], [3, 4], [5, 6], [7, 8]]

# 2. Decrease partitions to 2 using coalesce()
# Spark merges local partitions (e.g. 0 & 1, 2 & 3) without network shuffle
coalesced_rdd = large_partition_rdd.coalesce(2)

print("
--- After Coalesce ---")
print("New Partitions count:", coalesced_rdd.getNumPartitions()) # 2
print("Coalesced Layout:", coalesced_rdd.glom().collect())

# Typical Output:
# Coalesced Layout: [[1, 2, 3, 4], [5, 6, 7, 8]]
# Note: Elements from original partitions are combined locally without global network transfers!

3. What happens if you try to coalesce to a larger partition count?

By design, coalesce is built to avoid network shuffles. Therefore, it cannot increase the number of partitions. If you call .coalesce(N) where N is larger than the current partition count, Spark will simply ignore the call and retain your existing partition configuration.

rdd = sc.parallelize([1, 2, 3], numSlices=2)

# Attempt to increase partitions to 4 using coalesce
failed_coalesce_rdd = rdd.coalesce(4)

print("Attempted Coalesce Partitions:", failed_coalesce_rdd.getNumPartitions()) 
# Output: Attempted Coalesce Partitions: 2  (No change occurred!)

Tip

Performance Rule of Thumb

  • Decreasing Partitions: Always use coalesce() instead of repartition() to minimize network and disk overhead.
  • Increasing Partitions / Balancing Skew: Always use repartition() as it is the only way to spread data across new nodes and eliminate partition size inequalities.
Find this content helpful? ☕ Buy me a coffee

Entity Details

Create New Item

celebration
Enjoying the free content?

Create a free account to track your progress and save your place.

Create Free Account
help

Submit Technical Query

Have a question or run into an issue? Describe it below, upload an optional screenshot, and our engineering team will answer it!

image Attach image (optional)

Submit Feedback

build Free Developer Utility Free Tool
gavel

Privacy & Legal Disclaimer

1. Client-Side Browser Processing

All utility tools on DeepEngineerHub (including Image to PDF, Text Formatters, JSON Converters, and Encryptors) execute 100% locally within your client browser using WebAssembly and JavaScript. No uploaded images, text, or documents are transmitted, collected, or stored on remote servers.

2. Limitation of Liability ("As-Is" Provision)

Tools and services are provided free of charge for convenience and educational purposes "as-is" without warranties of any kind. DeepEngineerHub shall not be held liable for any data loss, formatting inconsistencies, or indirect damages resulting from tool usage.

3. Open Source & Third-Party Software

Certain utilities utilize open-source client libraries (such as jsPDF, Mermaid.js, Pyodide) licensed under MIT, Apache, or BSD open licenses. All intellectual property remains with their respective copyright holders.