Jump to content

Performance Question - Visitor Counter with dates..

Recommended Posts

What i wanna achive is a simple counter like that count up on visit (this is no problem) AND save the specific date (year/month/day) of the count...

in the end i will be able to get visits per day/per month/per year in a nice and dirty graph.

Just to have a way better simple counter system.

Should i only go with a complex setup of pages like this:

--stats (home template for pageviews)
----2018 (year)
------08 (month)
---------29 ->page_views   (integers on every day template)
---------30 ->page_views

Or just simple use:

--stats (home template for pageviews)
---->count (template) that holds simple field page_views and a date field

or could a fieldtype like tables (one table field for every month/year or so) be also a solution?

Or a own SQL table special for this and use it in a module? I don't have any experience on this topic...

What i have in mind of performance sideeffects on such a thing?

Or is there a solution that works with PW?

I wanna go the hard way and implement something like this:


only directly within PW and use the API to get the data...maybe create a simple module from it later i don't know if i  could set it up right from the start 😉

this is the reason for my questions on more experienced devs

Kind regards mr-fan


Share this post

Link to post
Share on other sites

Howdy @mr-fan!

This is just my $.02.

While PW can certainly handle such a simple task, to me, it is overkill. And I don't want 100K+ pages in my tree. In one project, I use a simple mysql table to store the unix timestamp as a simple counter. In another project, I use PW's features to track more complex data for affiliates. Regardless of the method you use, google analytics gives you the visitor data you used to get with dedicated visitor tracking scripts.

Even if you store visitor IP with the timestamp, you can use php's dns lookup to gather information on a desired ip address, although I don't recommend using that function on every ip entry.

I haven't noticed any performance degradation with either method. But I'm looking at only a few hundred to a few thousands hit per day on those domains. Your milage may vary. 🙂

Hope this helps.

  • Like 1

Share this post

Link to post
Share on other sites

That is the Point IP saving IP adresses is very bad....since may in europe....very bad...bad bad 😉 even a whois question is no more possible...so the rise of simple php hit counters (that was a great thing 10 years past) is on the way...

A other more complex workaround could be to setup a crownjob to read the apache logs and get needed data from there?

Share this post

Link to post
Share on other sites

You don't need to track an IP unless you are requiring information unique to a user. Just the timestamp in a mysql table is sufficient to give you a hit counter by date. There are quite a few apache log analyzers out there, but I haven't used them since google provides the information for me. I prefer to not make things more complicated than need be.

  • Like 1

Share this post

Link to post
Share on other sites

There‘ll certainly be a shift in what tools like google analytics need to be able to do in terms of preserving user privacy (and they already do), but I don‘t see anyone wanting to seriously build page counters in php again. Matomo (piwik) already exists and there are even new alternatives like fathom, which are already enough for simple needs.

  • Like 3

Share this post

Link to post
Share on other sites

+1 for Matomo

Share this post

Link to post
Share on other sites

I would probably do something like this:

Have a "stats" page somewhere (hidden), with one big raw textarea field.

Each visit would add one line to that field:


= page-id,user-role,username,unix-timestamp

You could get fancy and install a geo-IP-lookup PHP library and add lat/long infos as well.

Instead of using a comma-separated list for each item, you could save it as JSON. But I guess this would mean a slight performance hint on a bigger site (the bigger it gets, the more time it takes to transform JSON into an PHP array, add one item, and use json_encode again).

I've used a similar approach, when I played around with chatbots and certain API calls back and forth.

It would be quite easy to output some sort of stats / infographics from such raw data. And of course easy to export it to Excel or somesuch...

The only thing I would make sure and investigate some time before going that route: Check if there are some size-restrictions, i.e. how much data can actually be stored in a PW textarea field? Even this could be easily solved: Create a new stats-field for each year/month...

  • Like 1

Share this post

Link to post
Share on other sites

I had the need to do something similar before. 

We wanted to know how far users got into a multi-step order process, and also what values they were putting in during each step and the referring pages. 

I found inserting a record on every page load worked well and was fast. 

Don't increment anything or it is slow, just insert new records and use a weekly or monthly cron to process the data to keep the table size manageable. 

Add in an optimize command also to clear db overhead after rows are deleted. 

I insert the session_id, timestamp, ip address, etc, but none of the data is public.  Used for troubleshooting.

  • Like 2

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By LuisM
      Hi there,
      while developing a sideproject which is completly build with ProcessModules i suddenly had the urge to measure the performance of some modules 😉 as a result, say welcome to the FlowtiAppPerformance module. 
      It comes bundled with a small helper module called FlowtiModuleProfiler. In the first release, even though you could select other modules, it will track the execution of selected Site/ProcessModules. 
      This will give you the ability to gain insights how your Application behaves. 
      The Main Module itself will come with 2 Logging Options, Database or PW Logs. Select Database for Charts and Logs...well If you just want your profiles as a simple log file in PW. 
      You also could choose to dump the request profile into TracyDebugger as shown here:

      Dont wonder about my avg_sysload, somehow my laptop cant handle multiple VMs that good 😄
      Settings Screen



      again, dont look at the sysload 😄
      I will update the Module in the future to give some filter options and aggregation, but for now it satisfies my needs. 
      I hope it is helpfull for some. 
      Module is submited to the directory and hosted at github
      Any suggestions, wishes etc. are much appreciated. 
    • By quickjeff
      Hi Guys, I have seen some other threads that talk about this but nothing recent nor in line with what I need. 
      I have basically created a page in which I am tracking the number of views. I update the counter which is tied to a field I added to the page's template that I am tracking. The field is hidden from the website admin and only used for this data. 
      However, now I need to track it on a daily basis. I am thinking of keeping track of all time view total for 30 days and perhaps saving that and allowing the user to see the page views of last 7 days, each day as a number and then 30 days of data. This way if I want to build in reporting functionality I can. 
      What I need help with adding a date to the page_views field but also, knowing how many page_views for today, yesterday, day before etc. 
      Here is what I have so far and its working. Now I need to associate a date with every day. NOT every update of the page_views field. 
      if (!$user->hasRole('superuser')) { $page->page_views += 1; $page->of(false); $page->save('page_views'); $page->of(true); } echo $page->page_views; Any guidance, help, suggestions is absolutely appreciated. 
    • By Mobiletrooper
      Hey Ryan, hey friends,
      we, Mobile Trooper a digital agency based in Germany, use ProcessWire for an Enterprise-grade Intranet publishing portal which is under heavy development for over 3 years now. Over the years not only the user base grew but also the platform in general. We introduced lots and lots of features thanks to ProcessWire's absurd flexibility. We came along many CMS (or CMFs for that matter) that don't even come close to ProcessWire. Closest we came across was Locomotive (Rails-based) and Pimcore (PHP based).
      So this is not your typical ProcessWire installation in terms of size.
      Currently we count:
      140 Templates (Some have 1 page, some have >6000 pages)
      313 Fields
      ~ 15k Users (For an intranet portal? That's heavy.)
      ~ 195 431 Pages (At least that's the current AUTOINCREMENT)
      I think we came to a point where ProcessWire isn't as scalable anymore as it used to be. Our latest research measured over 20 seconds of load time (the time PHP spent scambling the HTML together). That's unacceptable unfortunately. We've implemented common performance strategies like:
      We're running on fat machines (DB server has 32 gigs RAM, Prod Web server has 32gigs as well. Both are running on quadcores (xeons) hosted by Azure.
      We have load balancing in place, but still, a single server needs up to 20 sec to respond to a single request averaging at around about 12 sec.
      In our research we came across pages that sent over 1000 SQL queries with lots of JOINs. This is obviously needed because of PWs architecture (a field a table) but does this slow mySQL down much? For the start page we need to get somewhere around 60-80 pages, each page needs to be queried for ~12 fields to be displayed correctly, is this too much? There are many different fields involved like multiple Page-fields which hold tags, categories etc.
      We installed Profiler Pro but it does not seem to show us the real bottleneck, it just says that everything is kinda slow and sums up to the grand total we mentioned above.
      ProCache does not help us because every user is seeing something different, so we can cache some fragments but they usually measure at around 10ms. We can't spend time optimising if we can't expect an affordable benefit. Therefore we opted against ProCache and used our own module which generates these cache fragments lazily. 
      That speeds up the whole page rendering to ~7 sec, this is acceptable compared to 20sec but still ridiculously long.
      Our page consists of mainly dynamic parts changing every 2-5 minutes. It's different across multiple users based on their location, language and other preferences.
      We also have about 120 people working on the processwire backend the whole day concurrently.
      What do you guys think?
      Here are my questions, hopefully we can collect these in a wiki or something because I'm sure more and more people will hit that break sooner than they hoped they would:
      - Should we opt for optimising the database? Since >2k per request is a lot even for a mysql server, webserver cpu is basically idling at that time.
      - Do you think at this point it makes sense to use ProcessWire as a simple REST API?
      - In your experience, what fieldtypes are expensive? Page? RepeaterMatrix?
      - Ryan, what do you consider as the primary bottleneck of processwire?
      - Is the amount of fields too much? Would it be better if we would try to reuse fields as much as possible?
      - Is there an option to hook onto ProcessWires SQL builder? So we can write custom SQL for some selectors?
      Thanks and lots of wishes,
      Pascal from Mobile Trooper
    • By FrancisChung
      Long but well written, detailed and informative article written by an Engineering Manager for Google Chrome about the true cost of Javascript and what you can do to alleviate some of that cost.
      Must read!

    • By dragan
      In page-edit view: If I wanted to display the total count of selections, is there an in-built PW method for this?
      e.g. let's say the default view is collapsed for a page reference field. I see the label "Services" but would like to see "Services (3)". I would know that three items are selected without opening the inputfield. And ideally after every change, the number gets updated (without page-reload).
      Did someone once built something similar?
  • Create New...