Peel and cut potatoes into 1-inch cubes, then dice the onion. Place potatoes and onion in a large pot and add enough water to cover them by about an inch. Bring to a boil over medium-high heat, then maintain a gentle boil until the potatoes are completely tender when pierced with a fork, about 15-20 minutes. This simultaneous prep and cooking approach saves time while the starches begin breaking down.
Carefully drain the potatoes and onions in a colander, reserving exactly 1 cup of the starchy cooking water in the pot. Return the drained potatoes and onions to the pot with the reserved water. Using a potato masher, mash the potatoes to your desired consistency—I prefer leaving some small chunks for texture rather than a completely smooth soup. The starchy water you reserved will help create a naturally creamy base without needing extra cream.
Stir the butter into the warm mashed potatoes until completely melted and incorporated. Pour in the milk while stirring constantly to create a smooth, creamy consistency. Add the garlic powder and season with salt and pepper to taste. Cook over medium heat for 6-7 minutes while stirring occasionally, allowing the flavors to meld and the soup to heat through without boiling.
Remove the pot from heat and let the soup rest for 5-10 minutes before serving. This resting period allows the flavors to fully develop and gives the soup a better mouthfeel. Ladle into bowls and serve with your favorite toppings such as crispy bacon, shredded cheddar cheese, sour cream, or fresh chives.