Skip to content

Conversation

@djeebus
Copy link
Contributor

@djeebus djeebus commented Jan 8, 2026

Mostly posting this for visibility right now.

4 MB read ahead, ReadAt = 12ms-45ms
joe_lombrozo@e2b-orch-client-djwm:~$ sudo ./simulator -read-method=ReadAt -drop-nfs-cache -nfs-stat /orchestrator/shared-store/  

==== reads ====
count: 100
min: 12.357989ms
p50: 18.470138ms
p95: 42.457205ms
p99: 43.757991ms
max: 45.82411ms
stddev: 11.766231ms

==== sizes ====
count: 100
min: 4.2 MB
p50: 4.2 MB
p95: 4.2 MB
p99: 4.2 MB
max: 4.2 MB
stddev: 0 B
nfs v4 client:  total:  1025
nfs v4 client:  read:   800
nfs v4 client:  open_noat:      100
nfs v4 client:  close:  100
nfs v4 client:  access: 8
nfs v4 client:  getattr:        1
nfs v4 client:  readdir:        16
4 MB read ahead, Read = 12-45 ms
joe_lombrozo@e2b-orch-client-djwm:~$ sudo ./simulator -read-method=ReadFile -drop-nfs-cache -nfs-stat /orchestrator/shared-store/  

==== reads ====
count: 100
min: 12.964908ms
p50: 39.625818ms
p95: 43.193261ms
p99: 44.80182ms
max: 45.016427ms
stddev: 12.697036ms

==== sizes ====
count: 100
min: 4.2 MB
p50: 4.2 MB
p95: 4.2 MB
p99: 4.2 MB
max: 4.2 MB
stddev: 0 B
nfs v4 client:  total:  1025
nfs v4 client:  read:   800
nfs v4 client:  open_noat:      100
nfs v4 client:  close:  100
nfs v4 client:  access: 8
nfs v4 client:  getattr:        1
nfs v4 client:  readdir:        16
128 KB (default) read ahead, Read = 21-100+ms
joe_lombrozo@e2b-orch-client-djwm:~$ sudo ./simulator -read-method=ReadFile -drop-nfs-cache -nfs-stat /orchestrator
/shared-store/  

==== reads ====
count: 100
min: 21.670188ms
p50: 27.763614ms
p95: 55.346971ms
p99: 114.461142ms
max: 122.071469ms
stddev: 14.161518ms

==== sizes ====
count: 100
min: 4.2 MB
p50: 4.2 MB
p95: 4.2 MB
p99: 4.2 MB
max: 4.2 MB
stddev: 0 B
nfs v4 client:  total:  1032
nfs v4 client:  read:   800
nfs v4 client:  open_noat:      100
nfs v4 client:  close:  100
nfs v4 client:  access: 8
nfs v4 client:  getattr:        1
nfs v4 client:  readdir:        16
nfs v4 client:  bind_conn_to_ses:       7
128 KB (default) read ahead, ReadAt = 21-90ms
joe_lombrozo@e2b-orch-client-djwm:~$ sudo ./simulator -read-method=ReadAt -drop-nfs-cache -nfs-stat /orchestrator/s
hared-store/  

==== reads ====
count: 100
min: 20.490773ms
p50: 26.766649ms
p95: 54.697701ms
p99: 85.661541ms
max: 90.233932ms
stddev: 11.499387ms

==== sizes ====
count: 100
min: 4.2 MB
p50: 4.2 MB
p95: 4.2 MB
p99: 4.2 MB
max: 4.2 MB
stddev: 0 B
nfs v4 client:  total:  1025
nfs v4 client:  read:   800
nfs v4 client:  open_noat:      100
nfs v4 client:  close:  100
nfs v4 client:  access: 8
nfs v4 client:  getattr:        1
nfs v4 client:  readdir:        16

Note

Adds tooling to measure storage read performance and export results for analysis.

  • New CLIs:
    • cmd/hammer-file: sequential/parallel GCS range reads with timing output and Mermaid Gantt files
    • cmd/simulate-gcs-traffic: configurable GCS read simulator (experiments for concurrency, gRPC opts, chunk size, etc.), CSV export with histograms, GCE metadata, and tests
    • cmd/simulate-nfs-traffic: NFS read simulator (concurrency, read method, read-ahead/sysctl tuning), optional nfsstat capture/parse, CSV export with Filestore metadata, and tests
  • Storage cache tweak: in storage_cache_seekable.go, read cached chunk via Read instead of ReadAt.
  • Build/module: go.mod updates (promote google.golang.org/api to direct dep).

Written by Cursor Bugbot for commit 1b5fd6e. This will update automatically on new commits. Configure here.

@djeebus djeebus changed the title add storage simulator script Create storage slab read simulator script Jan 8, 2026
@djeebus djeebus marked this pull request as ready for review January 14, 2026 19:26
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9d5bb30a5d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +120 to +121
for chunk := range fileSize / chunkSize {
offset := chunk * chunkSize

Choose a reason for hiding this comment

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

P2 Badge Read final partial chunk in parallel loop

The parallel read loop iterates for chunk := range fileSize / chunkSize, which truncates the chunk count. When the object size is not an exact multiple of chunkSize, the last partial chunk is never scheduled, so those tail bytes are skipped entirely and the timing stats for the parallel scenario underreport total work. This only shows up for non‑aligned object sizes; using a ceiling division (e.g., (fileSize+chunkSize-1)/chunkSize) or an explicit remainder check would ensure the final chunk is read.

Useful? React with 👍 / 👎.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is intentional

const totalAttempts = 10
totalChunks := info.size / f.chunkSize
for range totalAttempts {
offset := f.rand.Int63n(totalChunks-1) * f.chunkSize // the last one might not be full, just skip it
Copy link

Choose a reason for hiding this comment

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

Panic when file has only one chunk

Low Severity

The nextRead function computes totalChunks := info.size / f.chunkSize and then calls f.rand.Int63n(totalChunks-1). If a file has only one chunk (size between chunkSize and 2*chunkSize), totalChunks-1 becomes 0, and rand.Int63n(0) panics since it requires n > 0. While default parameters (100MB min file size, 4MB chunks) make this unlikely, changing flags or edge-case file sizes could trigger the panic.

Fix in Cursor Fix in Web

}
}

return errors.Join(errs...)
Copy link

Choose a reason for hiding this comment

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

System settings not restored if setup partially fails

Low Severity

The scenario.setup method continues processing all experiments even when one fails, collecting errors instead of stopping. If an early experiment like setReadAhead or setSysFs succeeds (modifying kernel parameters), but a later experiment fails, the function returns an error and the caller returns early without calling teardown. This leaves system settings (like /sys/class/bdi/.../read_ahead_kb or sysctl values) permanently modified until manual cleanup.

Additional Locations (1)

Fix in Cursor Fix in Web

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.

3 participants