This shows a 6mm truncated teardrop sliced with 0.25mm layers, with red highlighting the overlap.
A long time ago I mitigated this by adding 1/4 of the layer height to the radius, for reasons I can't remember now, but it isn't very accurate. There is some slight interference vertically and gaps at the sides.
I am currently designing a gearbox with ball bearings in 3D printed pockets, which I want positioned accurately, so I decided to revisit the problem.
The correct solution is simple: the compensated shape for the teardrop is simply the hull of itself shifted up half a layer and shifted down half a layer. That compensates the top half so that the bottom of the layer ends up on the circle and the bottom half so that the top of the layer ends up on the circle.
So now all the tips of the stairs sit exactly on the circle, except near the top where the 45 degree overhang would be exceeded.
This is what the hole looks like before it is sliced.
It does of course make the model specific to being sliced at a certain layer height, but my models tend to be designed that way anyway,
I printed this test piece with 6mm holes at different offsets from the layer boundary as well as holes from 1mm to 5mm and I tested it with plug gauges.
The gauges fit all the holes easily. Some are snug and some have a little play vertically depending on how the top edge aligns with the layer boundaries.
The bridge layers over the top come out a bit low because the filament forms a cylinder from a volume that would normally almost fill a rectangle, making it a slight interference fit when the top lines up exactly with the layers. In other cases there is a bit of vertical play due to the 45 degree limit at the top of the teardrop. This won't be an issue with my gearbox because it will be split into top and bottom halves and the top half will be printed upside down.
I have updated teardrop_plus() in NopSCADlib to use this method and also added a plus option to all the other variants like tearslot(). See https://github.com/nophead/NopSCADlib#Teardrops and https://github.com/nophead/NopSCADlib#Horiholes where you can find the code to make the test STL.
It should work universally as long as all slicers slice in the centre of the layer. Obviously it makes less difference with smaller layer heights.