There is something I can't understand in this code import asyncio async def fetch_data(param): print(f"Do something with {param}...") await asyncio.sleep(param) print(f"Done with {param}") return f"Result of {param}" async def main(): task1 = asyncio.create_task(fetch_data(1)) task2 = asyncio.create_task(fetch_data(2)) result2 = await task2 print("Task 2 fully completed") result1 = await task1 print("Task 1 fully completed") return [result1, result2] results = asyncio.run(main()) print(results) The output is Do something with 1... Do something with 2... Done with 1 Done with 2 Task 2 fully completed Task 1 fully completed ['Result of 1', 'Result of 2'] I expected to see Do something with 2... In the first line, but it outputs Do something with 1... first. It seems just creating tasks will run the coroutine, while from what I read and saw, it only registers it in the event loop. The flow should be From results = asyncio.run(main()) the main is registered into event loop Event loop runs the main Two tasks 1,2 are created and registered into the event loop, with status ready By result2 = await task2, the main is suspended fetch_data(2) is run From this flow, I expect to see Do something with 2... in the first line. Why does this output the Do something with 1...? first? To verify, I run this import asyncio async def fetch_data(param): print(f"Do something with {param}...") await asyncio.sleep(param) print(f"Done with {param}") return f"Result of {param}" async def main(): task1 = asyncio.create_task(fetch_data(1)) task2 = asyncio.create_task(fetch_data(2)) results = asyncio.run(main()) print(results) and the output is Do something with 1... Do something with 2... None Why are the couroutines running even without awaiting the tasks? Why does print(f"Done with {param}") not run in this version? Continue reading...