The difference, at least in the way this is built in Rust, is that when you create a task, you get a single allocation that's exactly sized. There's no resizing, which means that you aren't getting stacks that are too big or too small, with all of the other runtime shenanigans that that entails.
That said, the future has the size of the biggest state that need to be kept across await. The future might be slightly oversized, but still order of magnitude smaller than a perfectly sized stack.