[BUG] Per-session 1Hz `sh -c 'sleep 1' + date + ps` exec loop generates EDR telemetry storm & battery drain

Resolved 💬 4 comments Opened May 8, 2026 by TrevorBurnham Closed Jun 7, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Each running claude CLI process spawns a fresh /bin/sh -c ... subprocess approximately once per second, which in turn execs /bin/date, /bin/ps, and /bin/sleep 1. Every iteration creates brand-new (sequential) bash PIDs — i.e. the loop is shell-based, not a persistent child. With N Claude Code sessions open, this produces ~3N short-lived processes per second system-wide.

On machines with endpoint-security software that logs every exec() (FortiDLP, Tanium, CrowdStrike, etc.), this causes a sustained telemetry storm: every sleep, date, and ps is written to the EDR log, which drives measurable CPU/battery drain.

Key observations:

  1. Fresh bash PID per iteration (28853649 → 28853676 → 28853692 → ...). The loop is invoking system() / child_process.exec('sh -c ...') rather than keeping a persistent helper alive.
  2. Order is always date → ps → sleep, repeating every ~600–700 ms per session.
  3. Each claude child process I can see via ps has a live sleep 1 child with matching PPID:

``
28941 33514 sleep 1 # parent PID 33514 is a
claude process
28939 99189 sleep 1 # parent PID 99189 is a
claude process
28937 76700 sleep 1
28936 34817 sleep 1
``

Measured impact

Over a 30-second fs_usage -f exec capture on my machine (5 Claude sessions open):

| Child process (parent = bash) | Count in 30s |
|---|---:|
| /bin/date | 54 |
| /bin/sleep | 47 |
| /bin/ps | 47 |
| /bin/cat | 15 |
| Total bash-spawned execs | ~167 |

That is ~5.6 execs/sec from Claude Code alone, i.e. just over 1 full iteration per session per second. The cat entries are likely a separate helper (perhaps stdin reads), but the date/ps/sleep triad is the dominant, persistent pattern.

What Should Happen?

Idle Claude Code instances should not spawn subprocesses, as this causes significant CPU activity on machines with enterprise security software.

Error Messages/Logs

Steps to Reproduce

On macOS:

# While any Claude Code instance is running (but idle):
sudo /usr/bin/fs_usage -w -f exec bash sh 2>/dev/null | head -60

You will see a repeating triad per active Claude session:

17:41:31.970926  execve   /bin/date    0.001004   bash.28853649
17:41:31.988497  execve   /bin/ps      0.001770   bash.28853651
17:41:32.100139  execve   /bin/sleep   0.000308   bash.28853654
17:41:32.613523  execve   /bin/date    0.000449   bash.28853676
17:41:32.622288  execve   /bin/ps      0.000344   bash.28853678
17:41:32.709861  execve   /bin/sleep   0.000252   bash.28853683
17:41:33.219743  execve   /bin/date    0.000316   bash.28853692
17:41:33.229838  execve   /bin/ps      0.000256   bash.28853694
17:41:33.292868  execve   /bin/sleep   0.000273   bash.28853696
...

Claude Model

Not sure / Multiple models

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.132

Platform

AWS Bedrock

Operating System

macOS

Terminal/Shell

Other

Additional Information

Suggested fix

Replace the sh -c polling loop with an in-process timer. In Node this is as simple as setTimeout(tick, 1000) — no subprocess required, and the tick callback can read Date.now() and inspect the parent/children (if needed) via /proc or libproc/kinfo_proc bindings without fork+exec.

If the loop specifically needs:

  • a timestampDate.now() instead of exec('date')
  • a parent-alive checkprocess.kill(ppid, 0) or kqueue EVFILT_PROC NOTE_EXIT
  • process-list scanning → macOS libproc's proc_listallpids, or on Linux readdir('/proc'); avoid exec('ps')
  • a 1s delaysetTimeout / setInterval

Any of these eliminate the exec entirely and make the loop invisible to EDR.

Cross-references

Possibly related issues:

  • #22509 — macOS high CPU at idle (open)
  • #22275 — Linux equivalent (open)
  • #17142 — sched_yield/futex busy-wait
  • #22633 — main thread STAT=R busy-wait

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗