drupal cache_set / cache_get expiration
If you start chasing the code in cache_get you will eventually end up in DrupalDatabaseCache::getMultiple.  If you look at the code, you will see a call to DrupalDatabaseCache::garbageCollection at the top.  This will handle cache expiration before cron runs.

As part of system_cron you will see that cache_clear_all get called with NULL as the first parameter which


  $cid: If set, the cache ID to delete. Otherwise, all cache entries that can expire are deleted.


This cleans up the cache tables every time cron runs.

The Drupal 6 plumbing is different for pruning the cache (start reading cache_get, but the end result is essentially the same.

TL;DR, your cache TTL will always be honored when you get values, it's just the cache table cleanup that may not happen exactly when the TTL is up.