Mix yogurt, lemon juice, ginger paste, minced garlic, garam masala, cumin, coriander, turmeric, and chili powder in a bowl. Add your chicken pieces and coat everything thoroughly. Let it marinate for at least 15 minutes while you prep the rest (or up to 4 hours in the fridge if you're planning ahead).
Heat 2 tablespoons of butter in a large skillet over medium-high heat. Once it's foaming, add your sliced onion and cook until it softens and turns golden, about 5-6 minutes. Stir occasionally so it caramelizes evenly.
Add the marinated chicken (don't drain the marinade) directly into the pan with the onions. Sear for about 6-7 minutes until the chicken gets some color on the outside. It won't be cooked through yet, but you're building flavor here.
Pour in the tomato puree and stir everything together really well. Let it simmer for about 8-10 minutes, stirring occasionally. The sauce will start thickening and the chicken will cook the rest of the way through.
Reduce your heat to medium and slowly add the heavy cream, stirring constantly as you pour. Keep stirring until everything is smooth and combined (takes about 2-3 minutes). Don't panic if it looks a little watery at first—it thickens up.
Let the sauce bubble gently for another 5-7 minutes, tasting as you go. Adjust the spices if needed—I always add a pinch more garam masala because I like it really aromatic. The sauce should coat the back of a spoon when it's ready.
Turn off the heat and stir in your fresh cilantro. Taste one more time for salt and pepper, then serve immediately over rice or with naan bread. Mine always sticks a tiny bit to the pan at the edges and that's totally fine.