STM32 gotchas
15. Timer appears to run slower then is set

This assertion is usually brought up after an attempt to toggle a pin at MHz rate in a timer-triggered interrupt; often using "library" facilities, which further increase the execution time of the interrupt service routine (ISR). Usually, the execution time of processor is completely exhausted by the interrupts, and their execution rate (and thus the observed pin toggling) is then not given by the timer anymore, but by the mere execution time of the ISRs being continuously executed back-to-back.

Interrupts in the 32-bit mcus have a relatively high overhead (and, somewhat associated, relatively high latency), especially when compared to 8/16-bit mcus. The entry of interrupt alone, performed by hardware, takes 12 cycles in the Cortex-M mcus. Add to this the usual C function prologue and epilogue, and some code to perform the required action (e.g. toggling a pin), using "library" code and compiling at low or no optimization setting (usually to facilitate debugging), and an apparently minimal ISR can easily run several dozens or even a few hundreds of cycles long.

Generally, high rate interrupts are better to be avoided. Faster processes are preferrably be solved entirely by hardware, either using native facilities of the given peripheral modules (e.g. a pin to be toggled by the Output Compare/PWM mechanism of the Timer), or combining peripheral modules (e.g. using timer-triggered DMA), whenever possible.