In User::pingLimiter, when adding a cache entry for the rate limit, MediaWiki first adds an entry with an expiration: $cache->add( $key, 0, intval( $period ) ); // first ping than calls
$cache->incr( $key, $incrBy ); to increment the rate limit value.
XCache has some arguably buggy / unexpected behavior in this case: if a variable is added with a TTL and then incremented, the original TTL is lost. The TTL is set to either the parameter passed to xcache_inc (not done in Mediawiki) or the xcache default. This causes rate limiting to take much longer than expected or potentially never expire if using XCache defaults, locking users out when they hit rate limit thresholds. This was tested with the latest public release of XCache (3.2.0) and MediaWiki 1.28.2.