I don't do it in my head. I do diagrams, then discuss them with other people until everyone is on the same page. It's amazing how convoluted get data from db, do something to it, send it back can get, especially if there is a queue or multiple consumers in play, when it's actually the simplest thing in the world, which is why people get over-confident and write super-confusing code.
Diagrams are what I tend to use as well, my background is Engineering (the non software kind) for solving engineering problems one of the first thing we are taught to do at uni is to sketch out the problem and I have somewhat carried that habit over when I need to write a computer program.
I map out on paper the logical steps my code needs to follow a bit like a flow chart tracking the change in states.
When I write code I'll create like a skeleton with placeholder functions I think I'll need as stubs and fill them out as I go, I'm not wedded to the design sometimes I'll remove/ replace etc whole sections as I get further in but it helps me think about it if I have the whole skeleton "on the page"