The timing of time update packets is not perfect, so although the server runs at 20.0 TPS, the quotient of ticks to elapsed seconds between time updates floats around 20.0, sometimes higher than that and sometimes lower. If you entirely exclude "instantaneous" TPS samples above 20.0, the calculated average TPS is virtually always less than 20.
https://github.com/MCCTeam/Minecraft-Console-Client/blob/27e66433cdd1997a7ff69e0dfb7ca6d79646e30d/MinecraftClient/McClient.cs#L3307-L3346
The timing of time update packets is not perfect, so although the server runs at 20.0 TPS, the quotient of ticks to elapsed seconds between time updates floats around 20.0, sometimes higher than that and sometimes lower. If you entirely exclude "instantaneous" TPS samples above 20.0, the calculated average TPS is virtually always less than 20.