New to Kestra?
Use blueprints to kickstart your first workflows.
Orchestrate scheduled MariaDB housekeeping with Kestra. Purge expired transients, spam comments, and stale revisions in one transaction, then reclaim disk space.
Every WordPress (or other LAMP-stack CMS) installation running on MariaDB accumulates the same three kinds of bloat over time: expired transient cache entries in wp_options, spam comments that were never purged, and post revisions that pile up indefinitely. Left alone, these rows slow down every query that touches those tables and quietly grow the database file. This blueprint runs the cleanup as a scheduled, auditable job instead of a wp-admin plugin or a cron-triggered PHP script: it counts what is about to be removed, deletes it inside a single transaction, and reclaims the freed space with OPTIMIZE TABLE.
count_stale_rows (io.kestra.plugin.jdbc.mariadb.Query) runs one UNION ALL query that counts expired transients, spam comments, and post revisions older than revision_retention_days, and fetches all three counts in a single round trip.purge_stale_data (io.kestra.plugin.jdbc.mariadb.Queries) runs the three matching DELETE statements. With transaction: true (the default), a failure on any one of the three statements rolls back all of them, so the database never ends up with only a partial cleanup applied.reclaim_disk_space (io.kestra.plugin.jdbc.mariadb.Queries) runs OPTIMIZE TABLE against wp_options, wp_comments, and wp_posts to rebuild the tables and return the freed space to the filesystem instead of leaving it as unused page space.notify (io.kestra.plugin.slack.notifications.SlackIncomingWebhook) reports the three row counts from step 1 (which match what was purged, since the delete predicates are identical to the count predicates). The errors block posts a separate Slack alert if any step fails, calling out that the transaction rolled back.OPTIMIZE TABLE, not just rows marked as deleted.revision_retention_days) instead of a hardcoded cutoff.wp_options or wp_posts grow for months and wants a repeatable, observable way to trim it back.A WordPress cron job or a database-cleanup plugin can run the same DELETE statements, but it has no built-in transaction guarantee across multiple statements, no execution history to check what was purged last week, and no separate alert path when the job fails partway through. Kestra wraps the three deletes in one JDBC transaction via io.kestra.plugin.jdbc.mariadb.Queries, keeps a full log and row count for every run, and posts to a different Slack message on failure than on success, so a failed cleanup is never silent.
wp_options, wp_comments, and wp_posts tables (adjust table names if your prefix differs).SELECT, DELETE, and ALTER (for OPTIMIZE TABLE) privileges on those tables.MARIADB_URL: JDBC URL for the database, for example jdbc:mariadb://db-host:3306/wordpress?allowMultiQueries=true. The allowMultiQueries=true parameter is required for the Queries tasks to run multiple statements.MARIADB_USERNAME / MARIADB_PASSWORD: credentials for the database user.SLACK_WEBHOOK_URL: Slack incoming webhook URL.allowMultiQueries=true.count_stale_rows and purge_stale_data if your installation uses a custom table prefix.weekly_housekeeping trigger (or change the cron to match your maintenance window).WHERE post_status != 'inherit' style condition or extra tables (for example, wp_postmeta orphan rows) as additional DELETE statements in purge_stale_data.UPDATE ... SET comment_approved = 'trash') if you want a recovery window before permanent removal.count_stale_rows into a io.kestra.plugin.core.flow.If task to skip the Slack notification when nothing was purged.reclaim_disk_space to mirror the cleaned tables into a reporting warehouse.