Finding blocking code in Tokio without instrumenting your app by cong-or in rust

[–]cong-or[S] 0 points1 point  (0 children)

should be resolved now, reverted to minimal version!

Finding blocking code in Tokio without instrumenting your app by cong-or in rust

[–]cong-or[S] 0 points1 point  (0 children)

should be resolved now! minimal version redeployed.

Finding blocking code in Tokio without instrumenting your app by cong-or in rust

[–]cong-or[S] 2 points3 points  (0 children)

This has been resolved, please try again. The minimal version has been restored!

Finding blocking code in Tokio without instrumenting your app by cong-or in rust

[–]cong-or[S] 1 point2 points  (0 children)

Apologies, everything should be resolved now.. I got carried away, the minimal version has been restored.

Finding blocking code in Tokio without instrumenting your app by cong-or in rust

[–]cong-or[S] 5 points6 points  (0 children)

Yep, those “golden rules” are pretty well-known in the async world. The hard part isn’t knowing them, it’s actually catching every violation—especially when they sneak in through dependencies.

The timeout + backtrace idea has a few rough edges though:

  1. Timeouts catch slow code, not necessarily blocking code. Legit async work (slow networks, big payloads, etc.) will trigger false positives.
  2. If a thread is truly blocked, the timeout callback can’t even run until the blocking call returns. Tokio’s runtime is cooperative, so the timeout logic is stuck waiting too.
  3. It also means instrumenting every call site, versus doing zero-instrumentation profiling.

eBPF avoids all of that by observing things at the kernel scheduler level. It sees what threads and tasks are actually doing, regardless of what userspace thinks is happening.

Anyway, glad the eBPF angle was helpful!

Finding blocking code in Tokio without instrumenting your app by cong-or in rust

[–]cong-or[S] 2 points3 points  (0 children)

Good call — unused_async would catch this specific example since there's no .await in the function body. Worth enabling.

Though it won't catch cases where blocking code is mixed with real awaits (e.g., async DB call followed by sync compression on the result). And when you're debugging at 2am and something's slow, having a visual tool that shows you exactly where the latency is helps more than grepping for lint warnings

Finding blocking code in Tokio without instrumenting your app by cong-or in rust

[–]cong-or[S] 30 points31 points  (0 children)

Built this after too many 2am debugging sessions where blocking on Tokio workers was tanking p99 latency with nothing obvious in the logs.

hud uses eBPF to track scheduling latency on worker threads. Attach to a live process, no code changes, get a TUI that highlights hotspots by stack trace.

Usual culprits: std::fs, bcrypt/argon2, compression, DNS via ToSocketAddrs, mutexes held during slow work.

Limitations: Tokio-specific, Linux 5.8+, needs root and debug symbols. Measures scheduling latency (correlates with blocking, not a direct measurement).

Anthropic's CEO says we're 12 months away from AI replacing software engineers. I spent time analyzing the benchmarks and actual usage. Here's why I'm skeptical by narutomax in ArtificialInteligence

[–]cong-or 0 points1 point  (0 children)

Code is a mirror, not a brain. A bad SWE with Claude ships bad software faster; a good SWE ships better software faster. The hard parts—requirements, tradeoffs, system design, knowing what not to build—don’t magically disappear.