Preheat oven to 350 degrees
Remove the milk from the refrigerator and set aside to warm up before cooking.*you can also warm the milk in a saucepan on the stovetop. Wash and clean the potatoes, then slice them into ⅛” to ¼” slices using a sharp knife or mandolin rest in a bowl of cold water and set aside until needed
Place a large saucepan over medium heat.
When the pan is hot, add the unsalted butter and diced onions to the pan and cook until the onions are tender but not caramelized.
Add the chopped garlic and fresh thyme to the pan, stirring the mixture, and cook for an additional 2 minutes.
Add the flour to the pan and mix together until the flour has been absorbed into the butter, cooking for 1-2 minutes. This is the roux.
Add the chicken broth and milk to the pan, stirring to combine the mixture. Cook over medium-low heat for 2-3 minutes.Don't let the mixture get too hot or boil. Turn the heat down to low, then add the kosher salt, black pepper, and paprika to the mixture and simmer for 1 minute.
Remove the pan from the heat and set aside until needed.
Drain the potatoes and use paper towels to remove the excess moisture.
Butter a baking dish, then add a layer of potatoes along the bottom of the dish.
Add half of the cream sauce over top of the potatoes.
Sprinkle half of the shredded cheddar cheese and half of the parmesan cheese over top of the sauce.
Add a second layer of potatoes, then cover with the remaining cream sauce, then top with the remaining cheddar and parmesan.
Cover the baking dish with aluminum foil, then place it on the middle rack of the preheated oven, and bake for 40 minutes.
Carefully remove the aluminum foil from the pan and continue to bake for an additional 35 minutes or until golden brown and fork tender.
Remove the pan from the oven and let it cool for 15 minutes before serving. This will allow the creamy cheese sauce to set up a bit, so it's not too runny.