URLSession
In the documentation it says...
This handler is executed on the delegate queue.
And looking at the delegate queue...
All delegate method calls and completion handlers related to the session are performed on this queue. The session object keeps a strong reference to this queue until your app exits or the session object is deallocated. If you do not invalidate the session, your app leaks memory until it exits.
Note
This queue must be set at object creation time and may not be changed.
And looking at the init method...
It doesn't actually say anything about what type of queue is used...
Hmm...
As pointed out by @rmaddy a serial queue is created by the session so that would run on a background thread.
Conventions
As for conventions... there isn't really one.
If you write your own there are things to consider... is the completion likely going to update the UI? Will the completion do lots of data processing etc... and you can decide from there.
URLSession.shared
. Nor does it way what type of queue is created when you don't pass one into the init method. It just says that it will create a queue to perform the handlers. – Aggravation