Heat olive oil in a large pot over medium heat for about 1 minute. Add your diced onion and let it soften for 4-5 minutes until it turns translucent and smells amazing. Toss in the minced garlic and cook for another 30 seconds—don't let it burn or it gets bitter fast.
Sprinkle the all-purpose flour over the onion mixture and stir constantly for about 1 minute. You're creating a base that'll thicken everything up without lumps later. It should look kinda pasty right now, and that's exactly what you want.
Pour in your vegetable broth slowly while stirring, breaking up any flour lumps as you go. Add the crushed tomatoes plus the dried basil and oregano. Bring everything to a gentle simmer for about 15 minutes so the flavors can really meld together.
The soup will look a little thin at this point, but trust me—that's normal and it thickens up in the next steps. Reduce heat to low and stir in the milk, butter, salt, and sugar. Let it warm through for about 2-3 minutes, but don't let it boil hard or the milk can separate.
Here's my secret move: stir in the shredded mozzarella cheese right at the end and watch the tomato basil soup recipe transform into pure creaminess. It melts right in and adds this subtle cheesy depth you won't get any other way. Taste it now and adjust the salt or sugar if you need to.
If you like a smoother texture, grab an immersion blender and pulse it a few times. I personally leave mine slightly chunky because I like the texture, but totally your call. Keep it on low heat while you blend so nothing splatters everywhere.
Ladle into bowls and serve immediately while it's hot and steaming. The kitchen smells absolutely incredible at this point—seriously, your family will come running. Pair each bowl with a grilled cheese sandwich for the ultimate comfort meal.