Melt butter and olive oil in a large Dutch oven or heavy-bottomed pot over medium heat. Add sliced onions, salt, and pepper. Cook, stirring occasionally, until onions are softened and translucent, about 10-15 minutes.
Reduce heat to medium-low and continue cooking the onions, stirring frequently, until they are deeply caramelized and a rich brown color, about 45-60 minutes. Be patient; this slow caramelization is key to the flavor.
Sprinkle flour over the caramelized onions and stir well. Cook for 1-2 minutes, stirring constantly, to cook out the raw flour taste.
Gradually whisk in the beef broth and sherry (if using). Add the thyme sprigs and bay leaf. Bring to a simmer, then reduce heat to low, cover, and cook for at least 30 minutes to allow the flavors to meld.
While the soup simmers, preheat your broiler. Arrange the baguette slices on a baking sheet and broil until lightly golden on both sides. Rub one side of each toasted baguette slice with the halved garlic clove.
Remove thyme sprigs and bay leaf from the soup. Taste and adjust seasoning with salt and pepper if needed. Ladle the hot soup into oven-safe bowls.
Place a garlic-rubbed baguette slice on top of the soup in each bowl. Generously sprinkle the shredded Gruyere cheese over the baguette. Place the bowls on a baking sheet and broil for 1-2 minutes, or until the cheese is melted and bubbly and lightly browned.
Serve immediately, being careful as the bowls will be hot.
Notes
For an even richer flavor, you can add a splash of brandy along with the sherry. Ensure your bowls are broiler-safe.