Compliance5 min read

Setting Up a Data Retention Policy for Your WordPress Site

Data you don't need is data you're liable for. Learn how to define and automate retention policies for every type of data your WordPress site holds.

JO

James Okafor

Frontend Engineer · 8 March 2026

The Storage Limitation Principle

GDPR Article 5(1)(e) requires that personal data be "kept in a form which permits identification of data subjects for no longer than is necessary for the purposes for which the personal data are processed."

In plain English: delete data you no longer need. This is the storage limitation principle, and it's one of the most consistently overlooked aspects of GDPR compliance.

Why Retention Policies Matter Beyond Compliance

Keeping data longer than necessary isn't just a compliance risk — it's a security risk. Every record you hold is a potential liability in a data breach. Organisations that have been breached have faced significantly higher fines when regulators found they were holding data far beyond any reasonable retention period.

There's also a practical benefit: smaller databases are faster databases.

Building a Retention Schedule

A retention schedule maps each data category to a retention period and action on expiry. Here's a starting template for WordPress/WooCommerce sites:

Data CategoryRetention PeriodLegal Basis for RetentionAction on Expiry
Order records7 yearsTax obligation (HMRC)Anonymise customer details
Customer accounts (inactive)2 years from last loginLegitimate interestsDelete
Contact form submissions1 yearLegitimate interestsDelete
Newsletter subscriptionsUntil withdrawalConsentDelete + unsubscribe
Comments2 yearsLegitimate interestsAnonymise author details
Analytics sessions14 monthsLegitimate interestsPurge
Consent records3 yearsLegal obligationDelete
Audit logs3 yearsLegal obligationDelete
DSAR case records3 yearsLegal obligationDelete

Note: These are starting points, not legal advice. Your specific retention periods should be reviewed by a solicitor familiar with your industry and jurisdiction.

Legal Hold Overrides

Some data must be retained longer than your standard policy — typically because of a legal obligation or an ongoing dispute. Common legal holds:

  • Tax records — 7 years (UK, EU varies by country)
  • Employment records — varies significantly by jurisdiction
  • Litigation hold — data relevant to pending or anticipated litigation must be preserved

Your retention policy must accommodate legal holds without simply excluding all such data from automated deletion.

Implementing Legal Holds

// DPOKit hook: add a legal hold check
add_filter('dpokit_retention_should_delete', function($should_delete, $record) {
    // Prevent deletion of orders within UK tax retention window
    if ($record['type'] === 'woocommerce_order') {
        $order_date = new DateTime($record['created_at']);
        $tax_cutoff = new DateTime('-7 years');
        if ($order_date > $tax_cutoff) {
            return false; // Legal hold active
        }
    }
    return $should_delete;
}, 10, 2);

Automating Retention Enforcement

Manual deletion of expired data is unreliable. The solution is automated scheduled jobs that identify and act on expired records.

The Dry-Run Pattern

Before running any automated deletion, always implement a dry-run mode that shows you what would be affected:

# DPOKit WP-CLI: preview what retention enforcement would do
wp dpokit retention run --dry-run

# Output:
# Would anonymise: 847 WooCommerce orders (outside tax window)
# Would delete: 1,203 contact form submissions (>1 year old)
# Would delete: 89 inactive user accounts (>2 years inactive)
# Legal hold active for: 2,341 orders (within 7-year tax window)

Once you're satisfied with the preview, run without --dry-run to execute.

Rate Limiting Large Operations

Bulk deletion on a database with millions of records can cause serious performance problems. Always chunk large operations:

// Process in batches of 500 records to avoid timeout
function delete_expired_form_submissions() {
    $batch_size = 500;
    $deleted = 0;

    do {
        $ids = get_form_submissions_older_than('1 year', $batch_size);
        if (empty($ids)) break;

        foreach ($ids as $id) {
            delete_form_submission($id);
            $deleted++;
        }

        // Yield to avoid PHP timeout
        if ($deleted % $batch_size === 0) {
            sleep(1);
        }
    } while (count($ids) === $batch_size);

    return $deleted;
}

Audit Logging

Every automated deletion must be logged with:

  • Timestamp of deletion
  • Data category and count of records affected
  • The retention policy rule that triggered deletion
  • The action taken (delete vs anonymise)
  • Who or what system initiated the action

These audit logs are themselves personal data and subject to their own retention period (typically 3 years).

Tamper-Evident Logging

For regulatory compliance, your audit log should be tamper-evident. One approach is a hash chain:

function append_audit_log($entry) {
    $previous_hash = get_last_log_hash();
    $entry['previous_hash'] = $previous_hash;
    $entry['hash'] = hash('sha256', json_encode($entry));

    // Store the log entry
    wpdb_insert_log_entry($entry);

    return $entry['hash'];
}

Any modification to a previous log entry will invalidate all subsequent hashes, making tampering detectable.

Communicating Retention to Users

Your privacy policy must disclose your retention periods. Be specific — "we keep your data as long as necessary" doesn't meet the transparency requirements of GDPR Article 13.

DPOKit's auto-generated privacy notice draft pulls your configured retention periods directly into the privacy notice template, keeping documentation in sync with your actual policy.

Getting Started

  1. Audit what data you hold (use DPOKit's scan, or do it manually)
  2. Define retention periods for each category (use the table above as a starting point)
  3. Document your schedule in your ROPA
  4. Implement automated enforcement (DPOKit or custom WP-Cron jobs)
  5. Test with a dry-run before live enforcement
  6. Review annually — business needs and regulations change
JO

James Okafor

Frontend Engineer

Data RetentionGDPRWordPressAutomation