Place the diced potatoes in a large pot and cover with water. Bring to a boil and cook for 10–12 minutes, or until fork-tender. Drain and set aside.
Cook the bacon in a large soup pot until crisp. Transfer it to a paper towel-lined plate, leaving about 1 tablespoon of the rendered fat in the pot. Add the butter and diced onion, then sauté for 4–5 minutes until softened. Stir in the garlic and cook for 30 seconds.
Sprinkle the flour over the onion mixture and whisk continuously for 2–3 minutes to cook out the raw flour flavor. The mixture should form a smooth, lightly golden paste.
Gradually whisk in the chicken broth, followed by the milk. Continue stirring until smooth, then add the salt, pepper, basil, and celery salt. Bring to a gentle simmer and cook for 8–10 minutes until slightly thickened.
Stir in the heavy cream and cooked potatoes. Simmer gently for another 8–10 minutes, stirring occasionally. Lightly mash some of the potatoes with a potato masher while leaving plenty of chunks for texture.
Reduce the heat to low and stir in the shredded cheddar cheese until melted and smooth. Add sour cream if using, and avoid boiling the soup after adding the dairy.
Ladle the soup into bowls and top with crispy bacon, extra shredded cheese, and chopped green onions. Serve hot with crusty bread or crackers.