Post Views Counter persists view tracking data in four custom database tables. The core wp_post_views table is available in both Lite and Pro versions, providing the foundation for post and page view counting. Three additional tables extend tracking capabilities in Pro for taxonomy terms, traffic sources, and custom object types.
All table names use the WordPress configurable prefix (wp_ by default), which adapts to your installation’s $table_prefix setting in wp-config.php. Tables are created automatically during plugin activation through WordPress dbDelta() function calls.
Architecture
The database layer serves as the persistence foundation for the plugin’s tracking and reporting features. View counts flow from the counter mechanisms—PHP Mode, JavaScript Mode, REST API Mode, and Fast AJAX—into the wp_post_views table.
Counter Modes (PHP Mode, JavaScript Mode, REST API Mode, Fast AJAX)
│
▼
wp_post_views (post/page views — Lite + Pro)
│
<!-- pro -->
├──► wp_post_views_other (custom objects — Pro)
├──► wp_post_views_sources (traffic sources — Pro)
└──► wp_post_views_terms (taxonomy views — Pro)
<!-- /pro -->
Query operations are distributed across approximately 21 source files, with the primary query sites located in includes/class-counter.php, includes/functions.php, and includes/class-import.php. All database queries use $wpdb->prepare() for parameterized statements, preventing SQL injection vulnerabilities.
API Reference
wp_post_views
The primary table storing post and page view counts. This table is the foundation for all view tracking in both Lite and Pro versions.
| Column | Type | Nullable | Default |
|---|---|---|---|
id |
bigint |
NO | — |
type |
tinyint(1) |
NO | — |
period |
varchar(8) |
NO | — |
count |
bigint |
NO | — |
Column Semantics:
id— The post or object identifier (correlates with WordPress post IDs)type— Object type discriminator identifying the content type being trackedperiod— Time period identifier for aggregated counts (e.g.,total,2026-03,2026-W09)count— Cumulative view count for the specific id/type/period combination
Keys:
- PRIMARY KEY:
type,period,id— Optimized for lookups by content type and time period - UNIQUE INDEX
id_type_period_count:id,type,period,count— Ensures uniqueness and supports reverse lookups - INDEX
type_period_count:type,period,count— Optimizes aggregate queries filtering by type and period
The composite primary key design enables efficient retrieval of both total views and time-bounded views (daily, weekly, monthly) without requiring separate queries for each period type.
wp_post_views_other
Stores view counts for custom object types beyond standard posts and pages. This table enables tracking of arbitrary content types configured via Post Views > Counting > Tracking Targets.
| Column | Type | Nullable | Default |
|---|---|---|---|
id |
BIGINT(20) AI |
NO | — |
type |
TINYINT(1) |
NO | — |
subtype |
VARCHAR(?) |
NO | — |
Column Semantics:
id— Auto-incrementing unique identifier for the tracked objecttype— Primary object type classificationsubtype— Secondary classification enabling granular categorization within a type
Keys:
- PRIMARY KEY:
id— Auto-increment primary key for unique identification - UNIQUE INDEX
type_subtype:type,subtype— Ensures uniqueness of type/subtype combinations
wp_post_views_sources
Tracks traffic source attribution for view counts, enabling analytics on visitor origins. This supports the reporting and analytics features accessible through the Reports interface.
| Column | Type | Nullable | Default |
|---|---|---|---|
id |
BIGINT(20) |
NO | — |
type |
TINYINT(1) |
NO | — |
period |
VARCHAR(8) |
NO | — |
count |
BIGINT(20) |
NO | — |
content |
TINYINT(1) |
NO | — |
Column Semantics:
id— Related object identifier (correlates with content being viewed)type— Source type classification (e.g., search, social, direct, referral)period— Time period for aggregation (matches period format inwp_post_views)count— View count attributed to this source for the specified periodcontent— Content type discriminator for multi-type source tracking
Keys:
- PRIMARY KEY:
type,period,id,content— Composite key for efficient source-content-period lookups - UNIQUE INDEX
id_type_period_count:id,type,period,count,content— Ensures uniqueness across all dimensions - INDEX
type_period_count:type,period,count,content— Optimizes source-based aggregate queries
wp_post_views_terms
Stores taxonomy term view data, enabling tracking of category, tag, and custom taxonomy archive views. This supports the taxonomy tracking feature configurable at Post Views > Counting > Tracking Targets.
| Column | Type | Nullable | Default |
|---|---|---|---|
id |
INT(10) AI |
NO | — |
name |
VARCHAR(200) |
NO | — |
slug |
VARCHAR(200) |
NO | — |
parent |
INT(10) |
NO | — |
group |
VARCHAR(8) |
NO | — |
uid |
INT(10) |
NO | — |
Column Semantics:
id— Auto-incrementing term record identifiername— Term name (human-readable label)slug— URL-safe term slug for permalink structuresparent— Parent term ID for hierarchical taxonomies (categories)group— Grouping identifier for taxonomy type categorizationuid— Unique identifier for correlation with view count data
Keys:
- PRIMARY KEY:
id— Auto-increment primary key for unique term identification
Code Examples
Retrieving Post Views via Template Functions
The preferred method for accessing view data is through the plugin’s template functions, which handle database queries internally:
// Get total views for a specific post
$post_id = 123;
$total_views = pvc_get_post_views( $post_id );
// Get views for a specific time period
$monthly_views = pvc_get_post_views( $post_id, '2026-03' );
// Get views for multiple posts
$post_ids = array( 123, 456, 789 );
$views = pvc_get_views( 'post', $post_ids );
Direct Database Queries
For custom integrations requiring direct database access, use $wpdb with prepared statements:
global $wpdb;
$table = $wpdb->prefix . 'post_views';
// Get top viewed posts in a specific year
$top_posts = $wpdb->get_results(
$wpdb->prepare(
"SELECT id, SUM(count) as views
FROM {$table}
WHERE type = 0
AND period LIKE %s
GROUP BY id
ORDER BY views DESC
LIMIT 10",
'2026-%'
)
);
// Get views for a specific period range
$period_views = $wpdb->get_var(
$wpdb->prepare(
"SELECT SUM(count) FROM {$table}
WHERE id = %d
AND period BETWEEN %s AND %s",
$post_id,
'2026-01',
'2026-12'
)
);
Querying Pro Tables
Pro tables follow the same $wpdb->prepare() pattern for custom queries:
global $wpdb;
// Query term views from wp_post_views_terms
$term_table = $wpdb->prefix . 'post_views_terms';
$terms = $wpdb->get_results(
$wpdb->prepare(
"SELECT * FROM {$term_table} WHERE `group` = %s",
'category'
)
);
// Query source attribution from wp_post_views_sources
$sources_table = $wpdb->prefix . 'post_views_sources';
$sources = $wpdb->get_results(
$wpdb->prepare(
"SELECT type, SUM(count) as total
FROM {$sources_table}
WHERE id = %d
GROUP BY type
ORDER BY total DESC",
$post_id
)
);
// Query custom objects from wp_post_views_other
$other_table = $wpdb->prefix . 'post_views_other';
$custom_objects = $wpdb->get_results(
$wpdb->prepare(
"SELECT * FROM {$other_table} WHERE type = %d",
$custom_type_id
)
);
Integration with Multilingual Plugins
Pro includes specialized query handling for multilingual integrations:
// Polylang integration queries (includes/integrations/polylang.php)
// Uses $wpdb->prepare() for language-aware view queries
// WPML integration queries (includes/integrations/wpml.php)
// Uses $wpdb->prepare() for translation-aware view queries
