In a bowl, mix the oil, lemon juice, garlic, garam masala, turmeric, cayenne powder and salt.
Add the paneer cubes to the bowl.
Gently toss them with the marinade, making sure each piece is well coated. Be careful not to break the paneer. I find it easiest to use my hands.
Make the Sauce:
Heat oil over medium heat in a large saucepan or dutch oven.
Add onions and slowly cook until golden, reducing heat if they are getting crispy or browning quickly. This is an important flavour-building step, don't rush it.
Add garlic and ginger and cook until fragrant, about 1 minute.
Stir in garam masala, paprika, cinnamon and salt; cook 1 minute more.
Add tomatoes and cook 2 minutes.
Add cream and carefully puree using an immersion blender (or standing blender, but do it in batches or the steam will blow the top off).
Return sauce to saucepan and bring to a simmer. Stir in butter. Add up to 4 tbsp of water if the sauce is too thick.
Gently stir in paneer and cook until heated through, about 2 minutes.
Video
Notes
To make it ahead: Prepare the sauce up to 3 days in advance without adding cream or paneer and refrigerate it in an airtight container. On the day of serving, reheat it until it comes to a gentle simmer then add the paneer cubes and heavy whipping cream.
For a lightened-up or dairy-free recipe, you can replace it with coconut milk to achieve richness and consistency.
You may substitute the paneer with cubed halloumi or firm tofu. If using halloumi, cut the salt in half to account for the saltiness of the cheese.
Store leftovers in an airtight container for up to 4 days.