Both sides had early chances as Jak McCourt fired just wide for the hosts while Steve Morison went close to scoring against his former club with an audacious 40-yard chip which went just over.
The best chances came from set-pieces in a first half littered with free-kicks. Shaun Williams tested Adam Smith with a long range free-kick and Alex Revell fired over from 30 yards.
But Millwall broke the deadlock in the 32nd minute when Shaun Williams released Lee Gregory, who held off Zander Diamond before racing into the box and lifting the ball over Smith.
After the restart, substitute Sam Hoskins was denied by Jordan Archer who then tipped McCourt's 25-yard drive onto the bar.
In between, Morison volleyed wide before Cobblers were reduced to 10 men when McCourt got a second caution for bringing down Fred Onyedinma.
JJ Hooper's glancing header was saved by Archer before Calum Butcher doubled Millwall's lead on the hour mark, taking advantage of a slip by Brendan Moloney to beat the stranded Smith.
Morison was denied by Smith and Gregory's shot was deflected over. In between, David Buchanan twice fired over for Cobblers and Revell failed to get his header on target.
Substitute Marc Richards reduced the arrears in the 80th minute, heading home a cross from Hoskins. But Morison put the game beyond doubt in the 89th minute when he latched on to a long clearance to lob the advancing Smith.