Set a large saucepan over medium heat. Add the butter and 2 tbsp of olive oil. Once the butter is melted and slightly foamy, add the onions and a generous pinch of salt. Stir to combine, cover the pot and cook, undisturbed, for about 20 minutes - or until the onions have released their moisture and reduced in size by about half.
Remove the lid and cook, stirring occasionally, until the onions are deeply browned and caramelised all over - another 20-30 minutes. Add a splash of water here and there to deglaze the pan if there is any sticking.
Add the stock to a small saucepan and bring to a bare simmer. Keep simmering over low heat. Once the onions are deep golden brown, add the rice. Cook, stirring constantly, until the rice becomes slightly toasty and the perimeter turns translucent - 3-5 minutes.
Pour in the white wine, scraping up any browned bits that may have accumulated on the bottom of the pan. Stir until the wine has been absorbed into the rice and the strong alcoholic smell has cooked off - 3-5 minutes.
Ladle about 250ml (1 cup) of the hot stock into the rice mixture. Stirring constantly, let the stock absorb into the rice. Once the stock is fully absorbed, ladle in another 250ml (1 cup) of stock and repeat.
Continue stirring constantly and adding more stock in 120ml (½ cup) increments once the previous addition is absorbed until the rice is cooked through completely, about 15-20 minutes. You may not use all of the stock. Turn off the heat and stir in the Gruyere and parmesan cheeses. Season with salt and pepper to taste. Serve immediately, topping with more cheese if desired.