A real-time website gadget may want to display information such as:
7 people are listening now
12 people are viewing this property
5 people are shopping right now
18 visitors are currently using this tool
But before a gadget can display a live number, it needs to answer a deceptively difficult question:
What exactly makes a visitor "currently active"?
Opening a webpage does not necessarily mean someone is still using it.
A visitor may open an article and walk away. Someone may start a song and leave the browser tab open. A shopper may switch to another website. Someone may put their phone to sleep while the page remains loaded.
Therefore, a well-designed real-time gadget needs a clear definition of an active session, a method for detecting continued activity, and a rule for removing sessions that have become inactive.
This is the foundation of an accurate live counter.
An Open Browser Tab Does Not Equal an Active Visitor
The simplest implementation would be:
Page opened → Add visitor
Page closed → Remove visitor
Unfortunately, this is not reliable enough.
Browsers do not always provide a dependable notification when someone leaves a page.
A visitor might:
close the tab;
close the entire browser;
navigate to another page;
lose internet connectivity;
put their phone to sleep;
leave the tab open;
switch to another application;
move to another browser tab;
experience a browser crash.
The server cannot simply assume that a session is active because the initial page-load event happened.
This is why real-time systems generally use session expiration and heartbeats.
What Is a Heartbeat?
A heartbeat is a small periodic message sent by the gadget to the server.
Its purpose is essentially:
"This visitor's session is still alive."
For example, the gadget could send a heartbeat every 30 seconds.
The server might receive:
Session: A8271
Last seen: 10:15:00
Thirty seconds later:
Session: A8271
Last seen: 10:15:30
Another 30 seconds later:
Session: A8271
Last seen: 10:16:00
As long as these heartbeats continue arriving, the system considers the session active.
If the heartbeats stop, the session eventually expires.
This is much more reliable than relying on the visitor to explicitly close the page.
The Active-Time Window
The gadget also needs an activity timeout.
Suppose the heartbeat interval is 30 seconds.
You might decide:
A visitor is considered active if their last heartbeat was received within the previous two minutes.
The system can then use a rule such as:
Current time - last_seen <= 120 seconds
If that condition is true:
ACTIVE
If it is false:
INACTIVE
For example:
| Session | Last heartbeat | Status |
|---|---|---|
| A | 10:15:50 | Active |
| B | 10:15:20 | Active |
| C | 10:14:00 | Inactive |
| D | 10:12:30 | Inactive |
The server simply counts the sessions that fall within the defined activity window.
There Is No Universal "Correct" Timeout
The appropriate timeout depends on what the gadget is measuring.
This is one of the most important design decisions.
A music player, shopping page and calculator may require different definitions of activity.
For example:
| Gadget | Possible active definition |
|---|---|
| Music player | Audio actively playing + recent heartbeat |
| Online calculator | Recent interaction or heartbeat |
| Shopping page | Recent page activity + heartbeat |
| Property listing | Recent session heartbeat |
| Live chat | Open session + heartbeat |
| Online course | Active lesson/session + heartbeat |
| Game | Active connection |
| Article | Recent heartbeat, optionally combined with engagement |
These are examples rather than universal standards.
The gadget designer should choose the definition that best represents the activity being measured.
A Practical Starting Point: 30-Second Heartbeats
For many simple live counters, a reasonable starting architecture is:
Heartbeat: every 30 seconds
Active timeout: around 90–120 seconds
This creates a useful balance.
If the heartbeat is too frequent, the gadget generates unnecessary network traffic.
If it is too infrequent, the counter may remain inaccurate for too long after someone disappears.
For example:
10:00:00 → heartbeat
10:00:30 → heartbeat
10:01:00 → heartbeat
10:01:30 → heartbeat
If the visitor disappears after 10:01:30, the server eventually notices that no newer heartbeat has arrived.
Once the timeout is exceeded, the session is removed from the live count.
Why Not Remove the Visitor Immediately?
Suppose the gadget removes someone after only 10 seconds without a heartbeat.
A temporary network delay could cause:
Visitor active
↓
Network delay
↓
Heartbeat arrives late
↓
Visitor incorrectly removed
↓
Heartbeat arrives
↓
Visitor added again
The live counter might jump:
8 → 7 → 8
even though nothing meaningful changed.
A slightly longer expiration window provides tolerance for:
network delays;
mobile connections;
temporary browser throttling;
server delays;
background-tab behavior.
The timeout should therefore be long enough to avoid excessive false removals.
Why Not Keep Visitors Active for 30 Minutes?
The opposite problem occurs with an excessively long timeout.
Suppose someone opens your music page and leaves.
If your timeout is 30 minutes, the gadget might continue displaying that person as an active listener long after they have stopped listening.
You could end up with:
27 people listening now
when only a few are actually active.
That makes the statistic less meaningful.
The objective is therefore to find a practical balance between:
false inactivity
and
false activity.
Different Gadgets Need Different Activity Rules
This becomes particularly important for the systems you may eventually build.
Music Gadget
A music gadget should not necessarily count everyone who loads the page.
A better definition might be:
A visitor is an active listener when the selected audio is playing and the session has recently sent a heartbeat.
So:
Page opened
↓
Music not playing
↓
Not counted as listener
Then:
Visitor presses PLAY
↓
Listening session starts
↓
Heartbeat continues
↓
Visitor counted
If the visitor presses Pause:
Pause
↓
Listening session ends
This produces a much more meaningful "listening now" number.
Shopping Gadget
For shopping, you might define activity differently.
A visitor could be considered active if they have recently:
viewed a product;
searched;
filtered products;
opened a product card;
added an item to a cart;
interacted with the shopping interface.
However, simply having a product page open for several minutes does not necessarily mean the person is actively shopping.
You could therefore combine:
heartbeat + recent interaction
rather than relying on the page load alone.
Property Gadget
For a real-estate listing, the definition might be:
A visitor is active when their property-listing session has sent a recent heartbeat.
You could additionally record events such as:
property_view
photo_open
location_click
price_click
whatsapp_click
phone_click
inquiry_submit
Then the system can distinguish between:
Active visitors
and
Actual enquiries.
That distinction is valuable.
Someone viewing a property is not necessarily a lead.
Article or Blog Gadget
Articles are more complicated because people can spend long periods reading without clicking anything.
For example:
Visitor opens article
↓
Reads for 4 minutes
↓
No clicks
↓
Still potentially active
If you define activity only through mouse clicks, you may incorrectly classify the reader as inactive.
A heartbeat can therefore be useful.
You can optionally combine it with browser signals such as:
page visibility;
scrolling;
recent interaction;
focus state.
However, these signals should be treated carefully. A visible page does not prove that a human is actually reading it.
Page Visibility Can Improve the Model
Modern browsers provide visibility information that can help determine whether a page is currently visible.
For example:
Visible tab
↓
Potentially active
Hidden tab
↓
Potentially inactive
This can improve a basic system.
Suppose someone opens your music page and then switches to another tab.
The page may still exist, but it may no longer represent the visitor's current interaction with the gadget.
The gadget could respond to visibility changes by adjusting its heartbeat behavior or activity status.
However, visibility alone should not be treated as proof that the visitor is paying attention.
It is simply another signal.
Activity Should Be Based on Sessions, Not Personal Identity
For a basic live counter, you usually do not need to know who the visitor is.
Instead, create an anonymous session identifier.
For example:
session_id = X7A92K
The system stores:
session_id
gadget_id
page_id
started_at
last_seen
activity_type
status
The live counter then counts active sessions.
This is simpler and generally more privacy-conscious than attempting to identify individual people.
It also solves a practical problem: a visitor does not need to log into the website for the gadget to maintain a temporary session.
One Visitor Can Potentially Create Multiple Sessions
This is another reason to be careful with wording.
A person could open the same website:
on a phone;
on a laptop;
on a tablet.
That could produce three sessions.
Therefore:
3 active sessions
does not necessarily mean:
3 different people.
If the system cannot reliably determine unique people, it is technically safer to describe what it actually measures.
For example:
3 active visitors
may be acceptable depending on the identification model, but:
3 active sessions
is more technically precise.
The wording should match the measurement.
What Happens When a Visitor Closes the Page?
Ideally, the system can detect the end of the session quickly.
The browser may attempt to send a final event such as:
session_end
when the visitor leaves.
But this should not be the only mechanism.
Why?
Because the browser may not always successfully send that message.
The reliable backup is:
expiration based on last activity.
For example:
Final heartbeat:
10:10:00
Expiration threshold:
10:12:00
No activity after 10:10:00
↓
Session expires
↓
Removed from live count
This means the system can recover even when the visitor disappears unexpectedly.
The Server Should Be Responsible for Expiration
It is tempting to have the browser decide:
I am inactive, so I will remove myself.
But the server should ultimately control the active-session calculation.
The gadget sends:
heartbeat(session_id)
The server stores the latest timestamp.
When somebody requests the current count, the server calculates which sessions are still within the active window.
Conceptually:
active_sessions =
sessions where
current_time - last_seen <= timeout
This prevents the browser from manipulating the official count simply by changing its own JavaScript state.
Do Not Let the Counter Depend Entirely on the Displayed Number
The gadget should obtain the live count from the tracking system.
For example:
Gadget
↓
GET /active-listeners
↓
API
↓
Active-session store
↓
"7"
The gadget displays:
7 people listening now
The number should therefore come from the backend rather than being randomly generated or permanently stored in the HTML.
What If the Tracking Server Goes Offline?
A professional gadget needs a failure state.
Imagine that the music player itself works perfectly, but the analytics API is temporarily unavailable.
The gadget should not suddenly display:
0 people listening now
because that could falsely suggest that nobody is listening.
A better approach may be:
Live listener count temporarily unavailable
or simply hide the live counter while continuing to allow the music player to function.
The tracking system should not break the primary function of the gadget.
You Can Separate "Active" From "Engaged"
For more advanced systems, you can create multiple activity levels.
For example:
Online
The session is connected or has recently sent a heartbeat.
Active
The session has recently interacted with the gadget.
Engaged
The visitor has performed a meaningful action.
For a music site:
Online:
Page open
Active:
Audio playing
Engaged:
Audio playing for more than 30 seconds
For a property website:
Online:
Listing page open
Active:
Recent heartbeat
Engaged:
Photos viewed, location opened or enquiry initiated
This creates far more useful analytics than one generic "online" number.
A Useful State Machine
An advanced gadget can treat visitor activity as a series of states:
NEW
↓
ACTIVE
↓
IDLE
↓
EXPIRED
For example:
NEW
The visitor has just opened the gadget.
ACTIVE
The visitor is sending recent activity signals.
IDLE
The visitor has not interacted recently but the session has not yet expired.
EXPIRED
The session has exceeded the inactivity threshold and is removed from the live count.
This approach makes the system easier to reason about.
Example: A 2-Minute Activity Window
Suppose the system uses:
Heartbeat: every 30 seconds
Expiration: 120 seconds
A visitor's session might look like this:
10:00:00 Session created
10:00:30 Heartbeat
10:01:00 Heartbeat
10:01:30 Heartbeat
10:02:00 Heartbeat
At 10:02:30, the visitor has still been seen recently.
At 10:03:31, if no additional heartbeat arrived, the session is now beyond the two-minute window and can be considered expired.
The server therefore stops counting it as active.
This does not require perfect detection of the moment the browser closed.
The timeout provides a practical approximation.
The Live Counter Should Be an Approximation of Human Activity
This point is worth emphasizing.
A website cannot perfectly know whether a human being is physically looking at the screen every second.
Even sophisticated systems are estimating activity from signals.
Therefore, the objective should not be:
Detect exactly what every visitor is doing every second.
The objective should be:
Establish a consistent, technically defensible definition of active activity and apply it reliably.
Once the definition is established, the live counter becomes useful.
A Strong Configuration for a Reusable Gadget
If you are designing a reusable gadget that could work across Blogger, WordPress, Wix, Shopify, Webflow and standard websites, activity settings should ideally be configurable.
For example:
heartbeatInterval: 30 seconds
activeTimeout: 120 seconds
refreshInterval: 30 seconds
activityMode: "heartbeat"
requireInteraction: false
A music version might use:
activityMode: "media"
requirePlaying: true
A shopping version might use:
activityMode: "shopping"
requireInteraction: true
This is better than hard-coding one definition of activity into every gadget.
The Best Design Is Usually a Combination of Signals
For advanced gadgets, you do not necessarily have to choose between heartbeat, interaction and visibility.
You can combine them.
For example:
ACTIVE =
recent heartbeat
+
relevant gadget state
+
optional recent interaction
For a music player:
ACTIVE =
heartbeat
+
audio is playing
For an online calculator:
ACTIVE =
heartbeat
+
page visible
+
recent interaction
For a shopping interface:
ACTIVE =
heartbeat
+
recent shopping activity
The exact combination depends on the product.
A Practical Specification Before Coding
Before building the live counter, write down these decisions:
| Question | Example decision |
|---|---|
| What counts as active? | Recent heartbeat |
| Heartbeat frequency | 30 seconds |
| Expiration threshold | 120 seconds |
| Session identifier | Anonymous random ID |
| Additional signal | Page visibility |
| Gadget-specific signal | Audio playing |
| Server calculation | now - last_seen <= timeout |
| Counter refresh | Every 30 seconds |
| Historical events | Stored separately |
| Failed heartbeat | Retry |
| API failure | Do not show false zero |
| Privacy | Minimize personal data |
| Multiple devices | Treat as separate sessions unless deduplicated |
This specification should be completed before writing the JavaScript.
Final Takeaway
A visitor should not be considered "currently active" merely because a webpage was opened.
A better real-time system creates an anonymous session and periodically receives a heartbeat or other activity signal.
The server records the visitor's last_seen time and considers the session active while it remains within a predefined activity window.
For example:
Heartbeat every 30 seconds + approximately 2-minute expiration window
can provide a practical starting point for many simple gadgets, although the exact values should depend on what the gadget is measuring.
For specialized gadgets, additional signals can make the definition more meaningful:
Music: audio playing + heartbeat
Shopping: recent shopping activity + heartbeat
Property: recent listing activity + heartbeat
Courses: active lesson/session + heartbeat
General content: heartbeat + optional visibility/interaction signals
When the visitor stops sending valid activity signals and the timeout is exceeded, the server removes the session from the live count.
The most important principle is this:
The gadget should display what the system can actually measure—not what we merely assume is happening.
That principle becomes especially important when a live counter is used for business analytics, music engagement, property marketing, e-commerce or any other system where visitors may make decisions based on the displayed information.
No comments:
Post a Comment
We value your voice! Drop a comment to share your thoughts, ask a question, or start a meaningful discussion. Be kind, be respectful, and let’s chat!