I was doing a lot of stuff with the esp32 counters and timers a few months ago.
Some observations:
As the esp32 is running RTOS there is a lot of latency for external and internally triggered timers, occurring because many internal drivers are disabling interrupts all the time.
The PCNT devices on the esp32 can be triggered by a gpio trigger. This is 100% hardware, no interrupts. To count a long time you need to do some tricky mode changing as to use the GPIO to trigger the PCNT. You can use the normal GPIO interrupts to stop the time but this will be jittery and will be often have 5+ uS of misscount. You can use my code for this.
If you want to do a timer you need to use the new EVNT system or trigger the PCNT states with the PCNT hardware trigger.
I have a 10Mhz input from good GPSDO and a 1pps from a LEA-M8 and it does not miss any counts over days.
I count to a billion over 100 seconds gated by the GPS and it just prints out 1,000,000,000,000 over and over.
As far as a solution to your issue. I would probably try and use an Ublox M8T to generate a secondary clock source, maybe at 1Mhz and trigger this with the PCNT. While there is some phase noise if you are only looking to 1mS resolution it's a non issue.
The alternative is to use the 1pps to keep the internal clocks of different devices coherent. This is a bit trickier but not a big deal for 1mS. (I'd rather skip this one).
As others have said, OCXOs are only 20-30 bucks. I have a few. Most are badly implemented with the trimming network wrong so they can't be trimmed. You can mod them. I got one, unlike any of the others with no voltage reference but a much better circuit. If you are counting from this you need to level convert the output to 3.3V somehow. Once you do, the esp32 can count this perfectly. The one on my counter at the moment is sitting at an average of 10,000,000.001 Mhz for the last few weeks, with no dynamic disciplining but I would lower my expectations if it needs to be mobile.