There’s nothing wrong with threads.
But the promise of Fibers + a fiber scheduler is that you won’t have to think about the performance impact of blocking IO as much as you might normally.
For example, in a rails app (or any ruby web server) I am very scared to make slow external http requests because that might tie up a thread for a while, and request threads are a pretty limited resource in typical configurations. (16 threads/process) * (1 process/cpu core) might be a reasonable default, giving you at most 128 concurrent requests in flight on an 8 core server.
Suppose you make a really slow 3rd party api call that takes 10 seconds to service a request. Your server can handle no more than 128reqs/10s = 12.8 of these requests per second, even though it will spend most of its time doing nothing but waiting.
If we bring fibers in to the mix and do one fiber per request, then they can yield to another fiber while waiting on the api response - you can then easily have thousands of requests in flight instead of 128.
Granted, if you are entirely IO bound then you can probably get away with a much larger thread pool, or do thread-per-request. But if you have some other endpoints that are more compute intensive then bumping up your thread count might be dangerous... then what do you do? Fibers might be the answer.