ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
About

Plate 28

  1. Blog
  2. /Observability & SRE

glob vs rglob vs os.walk: Listing Lab

Hands-on glob.glob vs Path.rglob vs os.walk lab: real files/s for recursive file listing on a modest fixture tree, measured on Linux localhost for SREs.

Aditya Challa·30 September 2026·4 min read

Lab
On this page
  1. Intro — what this post promises
  2. Arms
  3. Lab topology
  4. Lead table — modest tree (p50)
  5. Wider tree (4,170 files)
  6. Reading it
  7. Fixture note
  8. Why isfile filters hurt
  9. Pitfalls
  10. When to pick what
  11. Reproduce
  12. Closing

Intro — what this post promises

Need every file under a tree: is os.walk, pathlib.Path.rglob, or glob.glob(..., recursive=True) fastest? This lab builds a modest fixture tree on disk and reports wall time / files/s on Linux localhost.

Related links:

  • pathlib vs os.path localhost lab
  • shutil copyfile vs manual localhost lab
  • json dumps compact vs indent localhost lab
  • str translate vs replace localhost lab
  • setdefault vs defaultdict localhost lab
  • itertools chain vs flatten localhost lab
  • hashlib md5 vs blake2b localhost lab
  • perf_counter vs time localhost lab

Lab honesty (1 Oct 2026 IST): Python 3.13.5. Fixture at lab-evidence/76-glob-vs-rglob-vs-walk/fixture_tree/. Affiliates: 0. “Files” arms filter isfile / is_file(); “all” arms include directories.

Verdict up front (modest, 1,210 files): os.walk ~1.30 ms (~929k/s) vs rglob+is_file ~5.95 ms vs glob+isfile ~6.19 ms. Walk led glob by ~4.8× and rglob by ~4.6×. Prefer os.walk for raw listing speed; rglob for Path ergonomics.


Arms

ArmPattern
os.walk filesjoin dirpath+filenames
os.walk countlen(filenames) only
Path.rglob("*")all entries / files filtered
Path.glob("**/*")equivalent glob on Path
glob.glob("**/*", recursive=True)stdlib glob + optional isfile

Trees: modest (depth 2) and wider (depth 3).


Lab topology

modest: ~1210 files; wider: ~4170 files
metric: p50 wall; entries/s
fixture persisted under lab-evidence/76-.../fixture_tree/

Script: lab-evidence/76-glob-vs-rglob-vs-walk/results/run_lab.py.


Lead table — modest tree (p50)

Armmsentries/s
os.walk files1.30929,424
os.walk count-only1.55782,611
Path.rglob files5.95203,484
glob recursive files6.19195,474
Path.rglob all2.69479,711
glob recursive all2.33552,566

Wider tree (4,170 files)

Armmswalk÷arm
os.walk files4.571.00×
Path.rglob files22.524.93×
glob recursive files21.434.69×

Same ranking at larger scale: walk ~4.7× glob files.


Reading it

  • os.walk wins listing — fewer Path object allocations; classic C-backed scandir walk.
  • rglob ≈ glob for files after is_file filters (~1.04× modest).
  • Filtering is costly — “all entries” glob/rglob is much closer to walk; isfile checks dominate the files arms.
  • Use Path when you need Path methods next; don’t pick rglob expecting a speedup over walk.

Fixture note

The tree is generated into evidence so you can re-list the same shape. It is not a kernel FS stress test — enough files to rank APIs, not millions of inodes.


Why isfile filters hurt

glob/rglob return directory entries too. Turning that into a file list means a metadata check per path. os.walk already separates dirnames from filenames, so the files arm mostly pays string joins. If you only need counts or names inside each directory, stay on walk and avoid a second pass of Path.is_file().


Pitfalls

  1. Comparing glob-all to walk-files — different entry sets (dirs included).
  2. Calling Path.is_file() on every rglob hit without needing stat — expensive.
  3. Assuming recursive glob is “free” — pattern matching + filters add up.
  4. Network FS / huge trees — re-measure; locality matters.

When to pick what

NeedPrefer
Fast file listos.walk
Path objects / suffixesPath.rglob
Simple pattern stringglob.glob(..., recursive=True)
Count onlywalk without building a giant list

Reproduce

python3 lab-evidence/76-glob-vs-rglob-vs-walk/results/run_lab.py

Evidence: /workspace/lab-evidence/76-glob-vs-rglob-vs-walk/results/ (+ fixture_tree/).


Closing

Walk to list; Path to ergonomics. On this box modest walk hit ~929k files/s, about ~4.8× glob+isfile and ~4.6× rglob+is_file. Reach for recursive glob when the pattern is the product; reach for walk when the product is “all files under here, fast.”

glob.globpath.rglobos.walkfile listingrecursive globpythonlocalhost labsre

Lab evidence

What I found running this

Lab 1 Oct 2026 IST. Python 3.13.5. modest (1210 files): os.walk 1.30ms / 929k/s; rglob-files 5.95ms; glob-files 6.19ms (walk~4.8x glob, ~4.6x rglob). Affiliates: 0. Evidence: lab-evidence/76-glob-vs-rglob-vs-walk/.

Notes when a lab post goes up

Occasional email for new hands-on reviews. No sequence and no sponsors.

Related links

  • Plate 18

    fnmatch vs re Name Filter: Localhost Lab

    Hands-on fnmatch.filter vs re.compile name-list filtering measured on Linux localhost.

    Observability & SRE · 30 Sept 2026

  • Plate 84

    tarfile vs zipfile Create+Extract: Localhost Lab

    Hands-on tarfile vs zipfile create+extract lab: real MB/s on a mixed small-file fixture (uncompressed tar vs zip), measured on Linux localhost for SREs.

    Observability & SRE · 30 Sept 2026

  • Plate 85

    scandir vs listdir vs iterdir: Localhost Lab

    Hands-on os.scandir vs listdir vs Path.iterdir lab: real entries/s for names and is_file on a synthetic tree, measured on Linux localhost (lab) for SREs.

    Observability & SRE · 30 Sept 2026

On this page

  1. Intro — what this post promises
  2. Arms
  3. Lab topology
  4. Lead table — modest tree (p50)
  5. Wider tree (4,170 files)
  6. Reading it
  7. Fixture note
  8. Why isfile filters hurt
  9. Pitfalls
  10. When to pick what
  11. Reproduce
  12. Closing
All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove