Appearance
Where Link Manager Pro stores data
Find where Link Manager Pro keeps its data in WordPress. Read settings the safe way, and see what deactivating or deleting the plugin removes.
Link Manager Pro keeps short links, clicks and settings in eight custom database tables, and keeps small state values in WordPress options, post meta, cookies and the uploads folder.
Read settings with the plugin's PHP settings class, not with SQL. The tables are described in Database tables.
At a glance
| Kind of data | Where it lives |
|---|---|
| Short links, clicks, affiliates, Link Health results, redirects, routing rules, Link Audit results | Seven custom tables with the prefix {$wpdb->prefix}link_manager_pro_ (Database tables) |
| Settings, short link addresses, campaigns, UTM templates, webhooks, coverage scores, deleted slugs | The eighth table, {$wpdb->prefix}link_manager_pro_meta |
| Plugin state, caches and locks | WordPress options and transients named link_manager_pro_*, lmp_* and lmpro_* |
| Which links a post holds, dismissed AI suggestions, Link Audit link targets | Post meta _lmp_link_map, _lmp_ai_dismissed_urls, _lmp_audit_link_targets |
| Category colors | Term meta color on the link_manager_pro_category taxonomy |
| Visitor tracking and password-protected links | Cookies link_manager_pro_id and lmpro_pw_{id} |
| GeoIP database, backup files | Folders in the uploads directory |
| Background jobs | Ten WP-Cron hooks |
Settings
Settings are stored as one JSON row per group in the plugin's meta table. Each row has entity_type set to setting, entity_id set to 0 and meta_key set to the group name.
The built-in schema has ten groups.
| Group | What it holds |
|---|---|
general | Short link prefix, internal prefix, affiliate prefix (empty by default), code length, masking on save, masking internal links |
notifications | Email digest frequency and recipient |
advanced | Who can use the plugin, report cache time, proxy trust, the delete-data switch |
integrations | Cache clearing and consent plugin behavior |
link_intelligence | Link Health scan schedule, content types, Link Audit thresholds, Link Equity values |
redirection | Global parameters, default redirect type, rel rules |
autolink | Auto-link limits and content types |
disclosure | Affiliate disclosure text and position |
tracking | Click tracking, retention, blocked IPs and bots, IP anonymizing, internal click tracking |
ai | AI source, provider, API key, model and limits |
All switches are the strings yes and no, never booleans. All keys use snake_case.
Read a setting with the settings class, using group.key. The class is LinkManagerPro\Services\Settings.
php
use LinkManagerPro\Services\Settings;
function myprefix_retention_days(): int {
return (int) Settings::get( 'tracking.click_retention_days', 0 );
}Don't query the meta table for settings. The stored shape is internal, and Settings::get() reads and decodes it for you. Pass a default as the second argument for a key that isn't saved yet.
After a group is saved, the plugin fires the link_manager_pro_settings_updated action with the group name, the new values and the old values. See Action hooks.
Stored encrypted
Two kinds of values are encrypted before they are stored.
- The AI API key,
ai.api_key, is encrypted when its group is saved. - Webhook signing secrets are encrypted when a webhook is saved.
Both use LinkManagerPro\Support\Crypto: AES-256-CBC with a key derived from the site's AUTH_KEY. A random 16-byte IV is stored in front of the ciphertext, and the result is base64. Changing AUTH_KEY makes stored secrets unreadable. A signed webhook whose secret can't be read fails its deliveries with secret_unreadable instead of sending unsigned.
Options and transients
The plugin's options and transients use three prefixes: link_manager_pro_, lmp_ and lmpro_. The uninstaller deletes every option and transient with these prefixes.
The main state keys:
| Option | What it holds |
|---|---|
link_manager_pro_version | The plugin version the tables were last migrated for |
link_manager_pro_onboarding | Setup status, current step and each step's state |
link_manager_pro_addresses | 1 or 0: whether any extra short link address exists |
link_manager_pro_address_conflicts | Links whose extra addresses are taken by something else |
link_manager_pro_previous_prefixes | Earlier short link, internal and affiliate prefixes, kept so old addresses still open. Each of the last 5 entries holds the prefix (base64, key p), the time 90 days after the change (until) and the setting it came from (k: link, internal or affiliate; left out when unknown) |
link_manager_pro_site_bases | Earlier site addresses, kept so Simple Redirects survive a domain move |
link_manager_pro_geoip | Checksum, size and download time of the GeoIP database |
link_manager_pro_geoip_dir_path | The folder the GeoIP database was last written to |
Caches and locks are transients with a time limit. For example, lmp_dashboard_stats caches the dashboard numbers and is deleted when the data changes. Scheduled tasks take a lock named lmp_cron_lock_* with a time limit of a few minutes, so two runs don't overlap.
Import and backup jobs keep their state in options named link_manager_pro_migration_job_{id} and link_manager_pro_backup_job_{id}.
Post and term meta
| Meta key | Type | What it holds |
|---|---|---|
_lmp_link_map | Post meta | A map from short link slug to the original URL, for the links in the post |
_lmp_ai_dismissed_urls | Post meta | URLs the editor dismissed in the AI assistant for this post |
_lmp_audit_link_targets | Post meta | The post IDs this post counts toward in Link Audit |
color | Term meta | The category color, a hex value such as #6B7280 |
Categories and tags are terms in two non-public taxonomies: link_manager_pro_category and link_manager_pro_tag. They have no admin screen of their own and no rewrite rules.
Cookies
Link Manager Pro sets two cookies, both only from short link requests.
link_manager_pro_id
The tracking cookie holds a random UUID that tells repeat visitors apart. It is set only when Click tracking is on, the visitor has no such cookie yet and consent is given.
- Lifetime: one year.
- Flags: path
/,HttpOnly,SameSite=Lax, andSecureon HTTPS. - The click row stores the UUID in
cookie_id.
Consent comes from the link_manager_pro_cookie_consent filter, which defaults to true. With Respect visitor consent on and a supported consent plugin active, the plugin sets the filter's answer from that plugin's category. Without consent, the plugin expires an existing tracking cookie and sets no new one.
Your own code can still have the last word.
php
add_filter( 'link_manager_pro_cookie_consent', 'myprefix_cookie_consent', 20 );
function myprefix_cookie_consent( bool $consent ): bool {
return ! empty( $_COOKIE['myprefix_accepted_stats'] );
}lmpro_pw_{id}
The password cookie is set when a visitor enters the right password for a password-protected short link, where {id} is the link ID. It holds a hash of the link ID and the stored password hash. It lasts one day, with path /, HttpOnly, SameSite=Lax and Secure on HTTPS.
Scheduled tasks
The plugin uses eleven WP-Cron hooks. Most are registered on the init action when missing.
| Hook | How often | When it is scheduled |
|---|---|---|
link_manager_pro_purge_clicks | Daily | On init. Also deletes expired backup files, prunes old deleted-slug rows and old visitor 404 rows |
link_manager_pro_scheduled_health_scan | Daily, weekly or monthly | On init, from link_intelligence.health_scan_schedule. Removed when it is disabled. An unfinished pass schedules a follow-up 30 seconds later. While that follow-up is pending, no second recurring event is added, and a schedule change applies once the pass ends. A one-time cleanup removes recurring events stacked by earlier versions (option lmp_health_scan_cron_cleaned) |
link_manager_pro_refresh_sitemap_cache | Twice daily | On init |
link_manager_pro_weekly_coverage_snapshot | Weekly | On init |
link_manager_pro_email_digest | Daily, weekly or monthly | On init, from notifications.digest_frequency. Removed when it is disabled |
link_manager_pro_migration_cron_batch | Once, with the job ID | Nothing in the plugin schedules the first run; imports run from the screen or WP-CLI. If an event exists, it runs one batch and schedules the next 60 seconds later while the import is unfinished |
link_manager_pro_webhook_drain | Every 5 minutes | On init |
link_manager_pro_webhook_nudge | Once | When a webhook delivery is queued and no nudge is pending. Runs the same drain |
link_manager_pro_webhook_purge | Daily | On init |
link_manager_pro_cache_trailing_purge | Once | About 30 seconds after a cache purge request that came inside the 30-second purge window, if none is pending |
link_manager_pro_address_recheck | Once, in steps | 30 seconds after an import, a restore, a change to any short link prefix, or a source plugin being switched on or off. Each step schedules the next after 15 seconds |
The plugin adds three custom intervals to WordPress cron:
| Interval | Length | Used by |
|---|---|---|
lmp_monthly | 30 days | The Link Health scan and the email digest |
link_manager_pro_monthly | 30 days | Kept for one release (until 1.4) so a digest queued under it stays valid; the digest now uses lmp_monthly |
lmp_five_minutes | 5 minutes | The webhook drain |
Files in uploads
Link Manager Pro writes inside wp-content/uploads/link-manager-pro/.
- GeoIP database:
geoip/dbip-country-lite.mmdb, written when you download the country database. The folder holds anindex.phpand a.htaccessthat denies direct access. - Backup files:
backups-{hash}/job-{id}/link-manager-pro-backup-{YYYYMMDD-HHMMSS}.json. The{hash}is the first 12 characters of a site-specific hash. The folder holds an.htaccessthat denies direct access, anindex.phpand anindex.html. Parts of an upload in progress go inupload-{id}folders next to the job folders.
Backup and upload folders expire one day after their last activity. The daily link_manager_pro_purge_clicks event removes them, except an unfinished restore.
Move the GeoIP folder with the link_manager_pro_geoip_dir filter. It receives the default folder path and returns the one to use.
php
add_filter( 'link_manager_pro_geoip_dir', 'myprefix_geoip_dir' );
function myprefix_geoip_dir( string $dir ): string {
return WP_CONTENT_DIR . '/private/geoip';
}The plugin records the folder it last wrote to in link_manager_pro_geoip_dir_path, so uninstall can clean it up.
Deactivate and uninstall
Deactivating clears every scheduled hook in the table above and removes the manage_link_manager_pro capability from the administrator and editor roles. Tables, options, files and settings stay. Activating adds the capability back to those two roles.
Deleting the plugin removes data only when Delete all data when the plugin is deleted is on and saved, under Link Manager › Settings › Advanced. On a multisite network, each site uses its own choice. With the switch off, WordPress removes the plugin files and leaves all data in place.
The same cleanup runs from WP-CLI, whatever the setting says:
bash
wp link-manager-pro uninstall --delete-dataThe command asks first. It then removes the data and deactivates the plugin. See WP-CLI for developers.
The cleanup removes:
- the eight tables, and any
{table}__lmpsnaprestore safety copies; - every option and transient with the
link_manager_pro_,lmp_orlmpro_prefix, including network-wide site transients on multisite; - all eleven scheduled hooks;
- the
manage_link_manager_procapability from every role that has it; - the terms of both taxonomies, with their relationships and term meta;
- the post meta keys
_lmp_link_map,_lmp_ai_dismissed_urlsand_lmp_audit_link_targets; - the
geoipandbackups-*folders in uploads, and thelink-manager-profolder once it is empty.
For a GeoIP folder moved with the filter, it removes only the database file and the two guard files it wrote, and the folder only if that leaves it empty. It refuses folders outside uploads or wp-content, and folders inside plugin or theme directories.
It doesn't remove your posts or their content, including any short links already written into them.
Multisite
Every site has its own tables, with that site's $wpdb->prefix, and its own options, settings and cron events. Network activation is refused: the plugin must be activated per site. When a site is deleted from the network, WordPress drops that site's Link Manager Pro tables and their __lmpsnap copies, through the wpmu_drop_tables filter.