Delays are a terrible solution. Looking at key overlap percentage, for example, works much better. There are a lot of other ways to make dual-use/tap-hold functionality more reliability, but lots of programs actually implement overlap checks. The kaleidoscope keyboard firmware, for example, lets you configure a minimum overlap threshold for a key to start acting as its secondary role (e.g. only have space act as a modifier when it is pressed first and is held for 70% of the time the second key is pressed).
In your case, I'm not sure why you would need to roll over to other keys from escape. My shift key doubles as escape, and I don't use any delay or checks at all since I don't rapidly type escape then other keys. In any case, you could try configuring your capslock key to only act as control if it being held fully overlaps with the next keypress. Not sure about keyd, but kmonad and kanata both support this (I'd highly recommend kanata). That may require changing how you type depending on the modifier, which is why more fine-grained overlap threshold checks can be useful.
In your case, I'm not sure why you would need to roll over to other keys from escape. My shift key doubles as escape, and I don't use any delay or checks at all since I don't rapidly type escape then other keys. In any case, you could try configuring your capslock key to only act as control if it being held fully overlaps with the next keypress. Not sure about keyd, but kmonad and kanata both support this (I'd highly recommend kanata). That may require changing how you type depending on the modifier, which is why more fine-grained overlap threshold checks can be useful.
Relevant github issues:
https://github.com/kmonad/kmonad/issues/351
https://github.com/jtroo/kanata/issues/128