My understanding is that you're trying to set a cache max-age of 0 (don't cache) for a paragraph. I think your issue here is that the max-age doesn't bubble up to the page level and the page cache still caches your paragraph. This makes it so your paragraph is not processed again.
My understanding is that cache max-age data doesn't bubble up to the page level from subelements. There are a couple open issues on d.o for this.
To me, it looks as though this is something that may not be resolved in core for a while (or maybe ever?). There is a contributed module, Cache Control Override that will bubble up the correct cache data to the page level. From the module's description:
In Drupal 8 core Page Cache max age settings are applied globally to
all pages, and there is no way to set a different max age per page or
leverage cache metadata max-age to override Cache-Control max-age
value. This means that if you're hosting your website behind a reverse
proxy that honors Cache-Control header, all pages are cached with
equal TTL. You can either disable cache with response policies, or
cache it for the same global value.
This module is intended to solve that problem by leveraging
cacheability metadata bubbled up to the page response level to
override Cache-Control max-age parameter.
If you install the Cache Control Override module, then set the max-age in your preprocess function, e.g.
$variables['elements']['#cache']['max-age'] = '0';, you should see your preprocess run every page load. However this will also ensure your pages with your paragraph never get cached at the page level. This could be a problem.
Depending on your site, it may be more prudent to use an alternative solution and render a placeholder in your paragraph and then use an ajax request to load the dynamic data into the placeholder. This will allow your full pages to stay cached while also allowing you to load dynamic data into your paragraph.