By executing, you mean you are calling methods on the Future Stub? If so, the completion of the future, and other callbacks, are executed on the executor provided to the channel when it was created (you can also fork the stub with your own executor). gRPC will always complete the future on executor passed in, as there may be requirements (like the presence of Thread Locals, etc.) on that executor. If you are worried about the app taking too long on one of the threads *you* provided to gRPC, you can always ask the application to provide you with an executor. If this is not possible, an you don't particularly care about threading overhead, you can use a cached threadpool which will bring new threads into existence if the app is blocking for too long. (Cached is also the default for gRPC itself, for the same reason).