As far as I can tell, the “only” (but potentially important) difference is, that @async sets the sticky bit on the created task, whereas @spawn does not (or rather, removes it, because it is set by default on newly created tasks). The sticky bit signals that a task is to be executed on the thread that schedules it only. A non-sticky task can be freely scheduled and moved around available threads.
Chances are you want @spawn.
use @macroexpand to see what each of @async, @spawn does.