In a large pot, melt butter over medium heat. Add diced onions and cook until translucent (5 minutes).
Stir in flour and cook for 1-2 minutes to make a roux.
Gradually add chicken broth, stirring constantly to prevent lumps.
Add diced potatoes and bring to a simmer. Cook until potatoes are tender (15-20 minutes).
Reduce heat to low. Add milk and cream, stirring to combine.
Gradually stir in grated cheese until melted and smooth.
Season with salt and pepper to taste.
Ladle into bowls and top with crumbled bacon, extra cheese, green onions, and a sprinkle of pepper or paprika.