Concurrency versus parallelism 11 served in the shortest amount of time possible, letting customers leave the bar with their beer faster and giving space to customers who want to make a new order. Now, this way, you can increase throughput even further. Y ou still won't reach the theoretical maximum, but you'll get very close. On the opening night, you realize that the bartenders now process 230 orders an hour each, giving a total throughput of 460 beers an hour. Revenue looks good, customers are happy, costs are kept at a minimum, and you're one happy manager of the weirdest bar on earth (an extremely efficient bar, though). The key takeaway Concurrency is about working smarter. Parallelism is a way of throwing more resources at the problem. Concurrency and its relation to I/O As you might understand from what I've written so far, writing async code mostly makes sense when you need to be smart to make optimal use of your resources. Now, if you write a program that is working hard to solve a problem, there is often no help in concurrency. This is where parallelism comes into play, since it gives you a way to throw more resources at the problem if you can split it into parts that you can work on in parallel. Consider the following two different use cases for concurrency: When performing I/O and you need to wait for some external event to occur When you need to divide your attention and prevent one task from waiting too long The first is the classic I/O example: you have to wait for a network call, a database query, or something else to happen before you can progress a task. However, you have many tasks to do so instead of waiting, you continue to work elsewhere and either check in regularly to see whether the task is ready to progress, or make sure you are notified when that task is ready to progress. The second is an example that is often the case when having a UI. Let's pretend you only have one core. How do you prevent the whole UI from becoming unresponsive while performing other CPU-intensive tasks? Well, you can stop whatever task you're doing every 16 ms, run the update UI task, and then resume whatever you were doing afterward. This way, you will have to stop/resume your task 60 times a second, but you will also have a fully responsive UI that has a roughly 60 Hz refresh rate.