My favorite "Rule of thumb" for the order of a low-pass FIR filter is the "fred harris rule of thumb":
delta(f) is the transition band, in same units of $f_s$
$f_s$ is the sample rate of the filter
atten(dB) is the target rejection in dB
For example if you have a transition band of 100 Hz in a system sampled at 1KHz, and your rejection requirement is 50 dB in the stop band then the order can be approximated by:
N= 1KHz/100Hz * 50/22 = 23 taps (rounding up)
Thank you fred harris!
Note another more detailed formula that takes into account passband ripple is Kaiser's formula thanks to James Kaiser from Bell Labs, which I included in my graphic below.
For most applications I have done, the fred harris approach has been just fine, as given a certain rejection, the resulting filters using traditional filter design algorithms such as Parks-McClellan and Remez have exceeded my passband ripple requirements upon meeting the rejection requirement. (What I usually do is estimate the order, design the filter with that order, inspect the result and increase or decrease order from there to fine tune). The results from the estimates are just that: estimates, and can vary widely depending on overall design parameters and not to be assumed to be an exact solution.
For those familiar with filter design using window approaches, review of the boxcar or rectangular window (which is simple truncation) reveals why it takes $f_s/\Delta f$ taps (which is the same as $2\pi/\Delta\omega$ if the units for normalized frequency are radians/sample as is often done) to complete the transition band. See the images below that help explain this.
The first image below shows the expected Sinc in frequency for a rectangular window in time, and then in discrete form, where it is an aliased Sinc function, with the key point that for N samples in time of the rectangular function, the frequency response will have its first null at f = 1/N (Where f is the normalized frequency with 1 being the sampling rate).
This next image shows the rectangular window approach to filter design (which I would never recommend but is informative). The first plot in the upper left hand corner shows the target frequency response for our filter as an ideal "brick wall" response. Please don't confuse that with the "boxcar window" (or "rectangular window") which is also a rectangular shape-- the window is in the time domain!
In order to realize such a filter, we would use the impulse response of the desired frequency response as the coefficients in our FIR filter (the coefficients of the filter are the impulse response---put an impulse in and out come all the coefficients!). The impulse response for a rectangular frequency (brickwall) response is the inverse FT which is a Sinc function, in the time domain, shown in the lower left hand corner as the "Required Impulse Response". A Sinc function extends to plus and minus infinity, so to actually realize such a filter we would need an infinitely long filter and it would have infinitely long delay. Obviously we can't do that, so we truncate the coefficients to something realizable. The longer the filter, the closer we approximate the ideal brickwall response, but also the longer the delay will be (and the more resources we would need in terms of the filter construction; more taps).
Truncating the impulse response in the time domain is mathematically identical to multiplying by a rectangular window in the time domain. (Note that the impulse response is also delayed by half the duration of the window in order for the system to be causal). Multiplying in the time domain is equivalent to convolution in the frequency domain. The frequency domain (FT) of the impulse response prior to truncation is our original desired brickwall frequency response. The frequency response for the rectangular window is a Sinc function in the frequency domain.
So when we truncate the desired impulse response (multiply in time by a rectangular window), we convolve the desired frequency response with a Sinc function, resulting in an approximation of our target frequency response as shown in the upper right-hand corner of the image below.
A key take-away for Sinc functions in general is the first null is 1/T where T is the duration of the rectangular function. For a sampled system, the first null would be at $2\pi/N$ where N represents the number of samples for the duration of the rectangular function. In the images a normalized radian frequency is used for the frequency axis- (if that confuses you just know the $2 \pi$ is the radian frequency for the sampling rate). So in the process of the convolution, the sharp brickwall transition spreads out and in this case goes to 0 (our $\Delta \omega$) over a frequency of $2\pi/N$! So here $$N = 2\pi/\Delta \omega$$ and of course the filter is poor with sidelobes etc. Note this: This transition from the Sinc function is the sharpest available for a given number of taps; it has the best resolution in frequency but the poorest dynamic range (rejection). Other window typologies (Blackman, Blackman-harris, Kaiser (my favorite), etc) will significantly improve dynamic range but always at the expense of the transition.
So from the above, we see the origin of the $2\pi/\Delta\omega$ that is used in the approximation formulas, and we also see why there is an additional multiplication factor increasing the number of taps above this for typical filter designs; the rectangular window would give us the best transition possible with N taps where $N = 2\pi/\Delta\omega$ but have very poor rejection. More taps are used to smooth the time transition further beyond the sharp transition of the rectangular window, providing greater rejection at the expense of transition bandwidth.