Heat the butter and oil in a large pot over medium heat. When the butter has melted and starts to foam, add the onions.
Cook the onions gently until they are very tender and translucent, approximately 10–12 minutes. Stir occasionally at first, then more frequently as the onions cook down to prevent burning.
Add the garlic, Italian seasoning, salt, and black pepper. Stir and cook for 1–2 minutes, stirring frequently.
Add the flour a little at a time, stirring constantly until well incorporated. Cook for 1–2 minutes to cook out the raw flour taste, stirring almost constantly.
Slowly add the chicken broth while stirring and gently scraping the bottom of the pot. Continue stirring until the flour mixture is incorporated into the broth.
Add the bay leaf. Raise the heat to medium-high and bring the soup to a simmer. Lower the heat to medium-low, half-cover, and cook for 20 minutes, stirring occasionally. Keep it at a gentle simmer, raising or lowering the heat as needed.
Find and remove the bay leaf and discard.
Take the pot off the heat and wait until the soup stops simmering. Process the soup in the pot with an immersion blender until smooth. If using a regular blender, do not fill it to the top with hot soup. Process the soup in batches.
Still off the heat, stir in the Gruyere cheese until melted. Stir in the half-and-half.
Place the pot back over medium-low to low heat and warm through. Don’t let the soup come to a simmer or boil.
Taste and add salt if needed. As a reference, we added ½ teaspoon to ours.
Serve and garnish with crispy fried onions, fresh parsley, and extra Gruyere cheese, if desired.