spawn_blocking runs a closure on a thread where doing blocking work won't prevent the tokio runtime from making progress on other tasks.
For example if I make a blocking network request inside a future on the tokio runtime, that runtime thread won't be able to process other tasks that are ready because the thread is waiting for the network request to finish.
Ideally you'd use an async aware API that lets you await the network request in this example, but that isn't always easy to do. So spawn_blocking fills that gap by making it easy to push blocking work off to a less important thread.