Skip to content

fix: reverting default cat_file concurrency back to 1 - #1051

Merged
ankitaluthra1 merged 3 commits into
fsspec:mainfrom
raj-prince:cat_file_concurrency
Sep 10, 2026
Merged

fix: reverting default cat_file concurrency back to 1#1051
ankitaluthra1 merged 3 commits into
fsspec:mainfrom
raj-prince:cat_file_concurrency

Conversation

@raj-prince

@raj-prince raj-prince commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

Problem

In release 2026.8.0, cat_file started using concurrency=DEFAULT_CONCURRENCY (4). Because concurrency > 1 by default, all cat_file calls branched into _cat_file_concurrent. When reading files of unknown size—such as Zarr metadata, Parquet metadata, and small files—this triggered an upfront _info() call, issued speculative HTTP range requests with extra round-trip latency. (#1048).

Solution

We restore single-request sequential reads as the default for cat_file by accepting concurrency via kwargs and defaulting to 1:

  • cat_file defaults to sequential (concurrency=1): Restores standard single-request GET (200 OK) without extra round-trips, _info() lookups.
  • Opt-in concurrency: Callers can still explicitly pass concurrency=... via kwargs (e.g., fs.cat_file(path, concurrency=4)) when concurrent fetching of large objects is desired.
  • Prefetcher untouched: GCSFile, ZonalFile, and _get_file continue to default to DEFAULT_CONCURRENCY = 4 for high-throughput streaming reads.

Microbenchmark cat_file result

1. Without Concurrency (concurrency=1)

File Size Min Mean Median Max Requests / op
8 B 421.02 ms 480.32 ms 452.52 ms 642.96 ms 1.0
64 KiB 422.02 ms 470.46 ms 432.61 ms 602.83 ms 1.0
1 MiB 512.60 ms 636.34 ms 579.25 ms 908.16 ms 1.0
4 MiB 688.91 ms 750.41 ms 694.12 ms 981.36 ms 1.0

2. With Concurrency (concurrency=4)

File Size Min Mean Median Max Requests / op
8 B 687.73 ms 756.77 ms 716.05 ms 940.57 ms 2.0
64 KiB 681.63 ms 747.52 ms 729.45 ms 896.83 ms 2.0
1 MiB 783.00 ms 838.45 ms 822.12 ms 969.60 ms 2.0
4 MiB 984.68 ms 1078.81 ms 1047.30 ms 1325.68 ms 2.0

Closes #1048

@raj-prince raj-prince changed the title fix: small cat_file regression due to concurrency fix: decouple default concurrency between cat_file and prefetcher Sep 9, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request decouples the default concurrency settings between cat_file and the prefetcher, reverting DEFAULT_CONCURRENCY to 1 while introducing DEFAULT_PREFETCHER_CONCURRENCY with a default of 4. Feedback includes validating that the DEFAULT_GCSFS_CONCURRENCY environment variable is strictly positive to avoid division-by-zero or other runtime errors, and removing duplicated text in the changelog entry.

Comment thread gcsfs/zb_hns_utils.py Outdated
Comment thread docs/source/changelog.rst Outdated
@codecov

codecov Bot commented Sep 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.19%. Comparing base (d4161bf) to head (dc15f0b).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1051   +/-   ##
=======================================
  Coverage   90.18%   90.19%           
=======================================
  Files          16       16           
  Lines        3740     3742    +2     
=======================================
+ Hits         3373     3375    +2     
  Misses        367      367           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@dhrp

dhrp commented Sep 9, 2026

Copy link
Copy Markdown

Thanks. By itself I think this is (also) a good solution for the problem we are observing. I tried to find out whether this unnecessarily leaves performance gains behind..

zarr always uses _cat_file(path) it won't benefit from the concurrency feature.

But is that a problem? Do other libraries also use this path?

I had Claude do a bit of analysis and put the gist here: https://gist.github.com/dhrp/c8804ae2ac0a2e16961366d0107d5499

@raj-prince raj-prince changed the title fix: decouple default concurrency between cat_file and prefetcher fix: reverting default cat_file concurrency to 1 no change for prefetcher Sep 9, 2026
@raj-prince

raj-prince commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks. By itself I think this is (also) a good solution for the problem we are observing. I tried to find out whether this unnecessarily leaves performance gains behind..

zarr always uses _cat_file(path) it won't benefit from the concurrency feature.

But is that a problem? Do other libraries also use this path?

I had Claude do a bit of analysis and put the gist here: https://gist.github.com/dhrp/c8804ae2ac0a2e16961366d0107d5499

Thank again for the analysis, discussed with the team and decided to go ahead with minimal safer change:

  • Zero-risk fix for the regression: Since cat_file is primarily intended for reading whole objects into memory (especially metadata and small files), defaulting cat_file concurrency back to 1 immediately restores original performance, zero-byte file handling, and avoids the _info() call altogether without changing HTTP semantics.
  • Avoiding low-level HTTP coupling: GCSFS currently does not inspect Content-Range response headers or intercept 416 status codes anywhere in the codebase. Introducing raw HTTP-level sniffing and error interception could complicate future architectural work (e.g. migrating standard buckets to modern SDKs or gRPC transports, where raw HTTP response headers and status codes are not exposed).
  • We are not against exploring the Content-Range probing optimization for explicit high-concurrency cat_file reads (concurrency > 1), but we'd prefer to defer that to a separate follow-up PR where we can thoroughly benchmark QPS, latency, and edge cases across workloads.

@raj-prince
raj-prince marked this pull request as ready for review September 9, 2026 13:25
@raj-prince raj-prince changed the title fix: reverting default cat_file concurrency to 1 no change for prefetcher fix: reverting default cat_file concurrency Sep 9, 2026
@raj-prince raj-prince changed the title fix: reverting default cat_file concurrency fix: reverting default cat_file concurrency back to 1 Sep 9, 2026
@googlyrahman

Copy link
Copy Markdown
Collaborator

Just saw this in your description, can you talk more on this?

and caused HTTP 416 errors on zero-byte files (https://github.com/fsspec/gcsfs/issues/1048).

I just tested reading both 0-byte objects and directory placeholder objects (0 bytes) on 2026.8.0, and both scenarios cleanly returned empty bytes (b'') without throwing a 416 error.

I thought the only concern is the additional HTTP call.

@raj-prince

Copy link
Copy Markdown
Collaborator Author

Just saw this in your description, can you talk more on this?

and caused HTTP 416 errors on zero-byte files (https://github.com/fsspec/gcsfs/issues/1048).

I just tested reading both 0-byte objects and directory placeholder objects (0 bytes) on 2026.8.0, and both scenarios cleanly returned empty bytes (b'') without throwing a 416 error.

I thought the only concern is the additional HTTP call.

My bad, that's AI generated summary - fixed it. Yes, the only concern is the additional HTTP call.

@googlyrahman

Copy link
Copy Markdown
Collaborator

You would need a change here as well cat_file defaults to sequential (concurrency=1): Restores ...., or 416 errors.

@dhrp

dhrp commented Sep 10, 2026

Copy link
Copy Markdown

Sounds good! I'll close my PR

@ankitaluthra1
ankitaluthra1 merged commit 96c3cfa into fsspec:main Sep 10, 2026
11 checks passed
ankitaluthra1 pushed a commit that referenced this pull request Sep 11, 2026
* fix: reverting default cat_file concurrency back to 1 (#1051)

* fix: default cat_file concurrency to 1 (#1048)

* removing nesting in unit test

* fixing failure

* updating relese change log

* removing unwanted test-case came during cherry-pick
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cat_file costs three HTTP round-trips per object since 2026.8.0, causing real slowdown on small files

4 participants