Concurrency bugs are some of the nastiest issues to debug in production, and a new technical analysis on DEV.to is making waves by arguing that running two executors on a single thread creates worse problems than running zero executors at all.

The Core Problem With Multiple Executors

The argument centers on executor starvation and priority inversion. When multiple async executors compete for the same thread's execution context, they can deadlock each other waiting for resources that only one can hold at a time. This isn't just theoreticalβ€”it's the kind of bug that passes unit tests and crashes production at 3 AM.

Why Zero Executors Can Actually Be Safer

Using no explicit executors often means relying on the runtime's default behavior, which is typically well-tested and handles context switching more predictably than multiple custom executors fighting over a single thread pool. The author argues that implicit concurrency is sometimes safer than explicitly managed concurrency gone wrong.

Common Pitfalls for Async Developers

The article highlights several anti-patterns: mixing blocking and non-blocking code on the same executor, creating nested executor contexts without proper isolation, and assuming thread affinity solves synchronization problems when it actually amplifies them in multi-executor scenarios.

Key Takeaways

  • Multiple executors on one thread cause priority inversion that single executors avoid
  • The default runtime executor is often more robust than custom configurations
  • Thread affinity doesn't replace proper async synchronization primitives
  • Testing alone won't catch these bugsβ€”they manifest under specific load patterns

The Bottom Line

If you're reaching for multiple executors to solve a concurrency problem, take a hard look at whether your architecture needs them. Sometimes the boring default path is actually the correct oneβ€”complex executor configurations are a footgun that most codebases would be better off avoiding.