Run code once on each page load
You can see an article on the subject here without using Events

https://chromatichq.com/blog/replacing-hookboot-and-hookinit-functionality-drupal-8

Possible that it will meet your needs.


  Replacing hook_boot and hook_init Functionality in Drupal 8
  
  The change notice page states:
  
  Using StackMiddleware
  
  This comment on the hook_boot change notice page provides an example
  of using StackMiddleware. It provides 95% of the functionality needed
  to run logic on cached pages by utilizing a tagged service with the
  http_middleware tag. Since the new class is a service, it will have
  full access to other core and contrib services, allowing for much
  greater functionality. The example shows the following for a module’s
  *.services.yml file:

services:   http_middleware.mymodule:
  class: Drupal\mymodule\StackMiddleware\MyModule
  tags:
    - { name: http_middleware, priority: 180, responder: true }

  
  This is a pretty standard service definition, but note the items added
  to the tags property that register our service with the
  http_middleware tag and also set a priority. In order to bypass the
  page cache, understanding the page_cache.services.yml file is helpful.
  There, a similar definition can be found, but with a higher priority
  value.

services:   http_middleware.page_cache:
    class: Drupal\page_cache\StackMiddleware\PageCache
    arguments: ['@cache.render', '@page_cache_request_policy', '@page_cache_response_policy']
    tags:
      - { name: http_middleware, priority: 200, responder: true }

  
  Higher priority services are run first. So to trigger logic before the
  page cache module takes over the request, a priority greater than 200
  is needed.

services:   http_middleware.mymodule:
    class: Drupal\mymodule\StackMiddleware\MyModule
    tags:
      - { name: http_middleware, priority: 210, responder: true }

  
  With this change in the services files, and proper setup of the
  service as described by the comment, the http_middleware.mymodule
  service should now be called on every page load, even on fully cached
  pages.

namespace Drupal\example\StackMiddleware;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;

/**
 * Performs a custom task.
 */
class ExampleStackMiddleware implements HttpKernelInterface {

  /**
   * The wrapped HTTP kernel.
   *
   * @var \Symfony\Component\HttpKernel\HttpKernelInterface
   */
  protected $httpKernel;

  /**
   * Creates a HTTP middleware handler.
   *
   * @param \Symfony\Component\HttpKernel\HttpKernelInterface $kernel
   *   The HTTP kernel.
   */
  public function __construct(HttpKernelInterface $kernel) {
    $this-&gt;httpKernel = $kernel;
  }

  /**
   * {@inheritdoc}
   */
  public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) {
    // Custom logic goes here.

    return $this-&gt;httpKernel-&gt;handle($request, $type, $catch);
  }
}

  
  Verifying the Results
  
  A quick and easy way to test all of this is to simply add
  \Drupal::logger('test')-&gt;notice(‘not cached’); into the functions
  triggered by each of the approaches above. Ensure that the Drupal
  cache is enabled, and simply refresh a page while watching your log
  (drush ws --tail). Then verify the logic is being called as expected.