Skip to main content
Personal blog

Simple, server-side page view analytics for Drupal

Computer screen with a screenshot of the analytics report

Are you looking for basic page view analytics for a Drupal site? You do not need the complexity of Google Analytics, and you definitely do not want to show visitors yet another cookie consent popup? Or maybe you value user privacy and prefer not to feed large tech corporations with behavioral data.

In all of these cases, I built a module for you.

Page Analytics provides simple, server-side page view analytics for Drupal, presented as clear charts and reports directly in the admin panel. No JavaScript tracking is required, which means no cookie banners and no privacy policy gymnastics. There are no third-party services involved, so you do not need to create accounts on external SaaS platforms or manage API keys. All results are stored directly in Drupal’s database.

Usage

Install and enable the module as usual.

composer require 'drupal/page_analytics:^1.0@beta'
drush en page_analytics

To start seeing data in the report, simply visit a few front-end pages. If the “Exclude logged-in users” option is enabled, make sure to visit them as an anonymous user. Then run cron. Why cron? More on that below.

You can find the report under Reports » Page analytics. There you will see a list of the most visited paths, each with a total view count and a chart showing daily visits over a selected time range (last week or last month). This makes it easy to spot overall volume, trends, and traffic peaks across your site.

The module also provides a configuration screen under Administration » Configuration » System » Page analytics, where you can fine-tune performance-related settings and, if needed, clear the collected analytics data.

Performance and how it works

Page Analytics records daily page view metrics with no noticeable impact on page rendering time. Thanks to a sampling mechanism and the use of Drupal’s Queue API, the module avoids doing work on every page request. Also, actual database writes do not happen during page requests at all, but only during cron runs.

Here is how it works under the hood:

On each successful (HTTP 200) response for a given path, the module records only a random, configurable fraction of page views.

  1. Eligible page views are added to a Drupal queue.
  2. When cron runs, a queue worker upserts records into the database table using the path and date as the key, incrementing the view count accordingly.
  3. The worker processes up to 100 items per cron run and applies the configured sampling rate when estimating total views.
  4. The report reads data from the database, and older rows are automatically removed during cron runs based on the configured retention period.

This approach keeps runtime overhead low while still providing meaningful, actionable insights.

Comparison with other modules

Drupal core (up to version 10) includes the Statistics module, which serves a similar purpose but offers a much more limited feature set. Below is a comparison between the core Statistics module, Page Analytics, and Google Tag–based solutions:

 StatisticPage AnalyticsGoogle Tag
Where tracking runsServer-side (PHP)Server-side (PHP)Client-side (JS)
Available statisticsLow - total views and today onlyMedium - daily counts shown as chartsHigh - enterprise-grade stats, charts and tools
Entry levelLow - plug-and-play, simple to use Low - plug-and-play, simple to use High - configuration both on the Google and Drupal sides, complicated to use
PrivacyHigh - no private data collectedHigh - no private data collectedLow - Full user tracking
Ownership of dataHigh - all stats inside your private databaseHigh - all stats inside your private databaseLow - stats are stored on an external platform

Available configuration

  • Sampling rate (1 in N)
    Defines the fraction of recorded page views (for example, 3 means 1 out of every 3 views is sampled). This helps reduce queue size and database writes on high-traffic sites. The report displays estimated totals. Higher values improve performance at the cost of accuracy. Use 1 for exact counts.
  • Keep data for (days)
    Specifies how long analytics data should be retained. Rows older than the configured number of days are automatically deleted during cron runs.
  • Excluding criteria
    Exclude admin paths, certain roles or certain paths from being counted.

Drush

The module includes a Drush command useful for debugging and fine-tuning settings

  • drush page-analytics:status (alias: drush past) — Shows queue size, table row count, last cron run, and current config.

Development status

The module is available for Drupal 11 and is currently in beta, ready for community testing. It also awaits the security advisory coverage application. I encourage you to try it out. If you notice any issues or come up with ideas for new features, feel free to open an issue on the module’s project page. Feedback and contributions are always welcome.

About the author

Written by

Michał Kokociński

Mixes skills from both the JavaScript and PHP ecosystems. After starting in Drupal, he transitioned into React applications. He has since returned to the Drupal ecosystem, where he applies modern frontend methodologies to Drupal 11 and contributes actively to open source. He also leverages LLMs and AI coding to deliver quality software with optimized effort.

See my other posts

All posts
A guy on a street deciding where to go next

Where Drupal Still Wins in 2026?

6 minutes read

Coming back to Drupal after years away, while working primarily as a frontend developer in the long-established React ecosystem with TypeScript and its surrounding tech stack, a natural question emerged: does starting new projects on Drupal in 2026 still make sense?

Read more