Spaces WP-CLI Automation & Cron Setup

SPACES exposes a set of WP-CLI commands to manage data imports for properties. These commands are designed for larger clients with multiple properties where data imports need to run efficiently and in parallel, bypassing the WordPress cron system in favor of the OS-level cron (crontab).

📘

This is only available in versions Spaces 2.11 or later.

By scheduling imports through the system cron, you can:

  • Run imports for multiple assets simultaneously in parallel processes.
  • Avoid the limitations and unreliability of WP-Cron on high-traffic or cached sites.
  • Precisely control import timing and frequency.
  • Distribute load across staggered schedules.

Table of Contents


Available Commands

CommandDescription
wp spaces versionPrints the current SPACES plugin version
wp spaces engrain_asset_idsReturns Engrain asset IDs from the database
wp spaces import_pricing <id>Imports pricing data for a single asset
wp spaces import_content <id>Imports content for a single asset
wp spaces import_floor_plans <id>Imports floor plans for a single asset
wp spaces import_units <id>Imports units for a single asset
wp spaces update_unit_inventory <id>Updates unit inventory for a single asset

wp spaces version

wp spaces version
# SPACES 2.8.0

Spaces WP-CLI Command Guide

The Spaces plugin provides a set of WP-CLI commands for importing and managing property data directly from the command line.

These commands are typically used in environments where multiple assets must be imported automatically using system cron jobs, rather than relying on the default WordPress WP-Cron scheduler.

Using WP-CLI with system cron allows you to:

  • Run imports for multiple assets in parallel
  • Avoid reliability limitations of WP-Cron
  • Precisely control import timing and frequency
  • Distribute server load through staggered schedules

Command Overview

CommandDescription
wp spaces versionReturns the installed Spaces plugin version
wp spaces engrain_asset_idsLists Engrain asset IDs connected to the CMS
wp spaces import_pricing <asset_id>Imports pricing data for an asset
wp spaces import_content <asset_id>Imports content for an asset
wp spaces import_floor_plans <asset_id>Imports floor plan data
wp spaces import_units <asset_id>Imports unit data
wp spaces update_unit_inventory <asset_id>Updates unit inventory

Check Installed Spaces Version

Returns the currently installed Spaces plugin version.

wp spaces version

Instead of relying on WordPress cron (WP-Cron), these commands are intended to run through system-level cron jobs (crontab).

Using system cron allows you to:

  • Run imports for multiple assets in parallel
  • Avoid WP-Cron reliability issues on high-traffic or cached sites
  • Precisely control import timing and frequency
  • Distribute server load through staggered scheduling

Available Commands

Check Installed Spaces Version

Returns the currently installed Spaces plugin version.

wp spaces version

wp spaces engrain_asset_ids

Supports batching and output formatting.

wp spaces engrain_asset_ids              # table with last imported timestamps
wp spaces engrain_asset_ids --field=id   # plain list of IDs only
wp spaces engrain_asset_ids --field=id 25
wp spaces engrain_asset_ids --field=id 25 1
wp spaces engrain_asset_ids --format=csv
wp spaces engrain_asset_ids --format=json

Positional Arguments

ArgumentDescription
<batch_size>Maximum number of assets to return
<batch_seq>Zero-indexed batch offset. Skips batch_seq * batch_size rows

Flags

FlagDescription
--field=idOutput only the asset IDs
--format=<format>Output format: table, csv, json. Default: table

wp spaces import_pricing <id>

wp spaces import_pricing 123
# Beginning pricing data import for asset_id: 123 , pricing_process_id: 456
# Completed pricing data import for asset_id: 123 , pricing_process_id: 456

wp spaces import_content <id>

wp spaces import_content 123
# Beginning content import for asset_id: 123
# Completed content import for asset_id: 123

wp spaces import_floor_plans <id>

wp spaces import_floor_plans 123
# Beginning floor plans import for asset_id: 123 , pricing_process_id: 456
# Completed floor plans import for asset_id: 123 , pricing_process_id: 456

wp spaces import_units <id>

wp spaces import_units 123
# Beginning units import for asset_id: 123 , pricing_process_id: 456
# Completed units import for asset_id: 123 , pricing_process_id: 456

wp spaces update_unit_inventory <id>

wp spaces update_unit_inventory 123
# Beginning unit inventory update for asset_id: 123 , pricing_process_id: 456
# Completed unit inventory update for asset_id: 123 , pricing_process_id: 456

Scheduling Imports with Crontab

The recommended approach for production is to use the system crontab, replacing WP-Cron for these operations.

Prerequisites

  • WP-CLI must be installed and accessible on the server.
  • The wp command must be able to reach the WordPress installation (correct --path flag or run from WordPress root).
  • The cron user must have permission to execute WP-CLI and access WordPress files and the database.

Recommended Schedule

Import TypeFrequencySchedule
Floor PlansOnce per day9:00 AM UTC
ContentOnce per day10:00 AM UTC
PricingOnce per day11:00 AM UTC
Unit InventoryOnce per hour:15 past every hour

Sequential Imports

# Floor plan imports — daily at 9:00 AM UTC
0 9 * * * for id in $(/usr/local/bin/wp spaces engrain_asset_ids --field=id --path=/var/www/html --allow-root); do
/usr/local/bin/wp spaces import_floor_plans "$id" --path=/var/www/html --allow-root; done

# Content imports — daily at 10:00 AM UTC
0 10 * * * for id in $(/usr/local/bin/wp spaces engrain_asset_ids --field=id --path=/var/www/html --allow-root); do
/usr/local/bin/wp spaces import_content "$id" --path=/var/www/html --allow-root; done

# Pricing imports — daily at 11:00 AM UTC
0 11 * * * for id in $(/usr/local/bin/wp spaces engrain_asset_ids --field=id --path=/var/www/html --allow-root); do
/usr/local/bin/wp spaces import_pricing "$id" --path=/var/www/html --allow-root; done

# Unit inventory updates — every hour at :15
15 * * * * for id in $(/usr/local/bin/wp spaces engrain_asset_ids --field=id --path=/var/www/html --allow-root); do
/usr/local/bin/wp spaces update_unit_inventory "$id" --path=/var/www/html --allow-root; done

Parallel Imports

Use & to background each import and wait to block until all complete.

0 11 * * * for id in $(/usr/local/bin/wp spaces engrain_asset_ids --field=id --path=/var/www/html --allow-root); do
/usr/local/bin/wp spaces import_pricing "$id" --path=/var/www/html --allow-root & done; wait

Batched Parallel Imports

For sites with 50+ assets, split the workload across staggered cron entries. The engrain_asset_ids command supports batching via <batch_size> and <batch_seq>.

Example:

wp spaces engrain_asset_ids --field=id 25 0 → assets 1–25
wp spaces engrain_asset_ids --field=id 25 1 → assets 26–50
# Pricing imports — Batch 0 (assets 1-25) at 11:00 AM UTC
0 11 * * * for id in $(/usr/local/bin/wp spaces engrain_asset_ids --field=id 25 0 --path=/var/www/html --allow-root); do
/usr/local/bin/wp spaces import_pricing "$id" --path=/var/www/html --allow-root & done; wait

# Pricing imports — Batch 1 (assets 26-50) at 11:01 AM UTC
1 11 * * * for id in $(/usr/local/bin/wp spaces engrain_asset_ids --field=id 25 1 --path=/var/www/html --allow-root); do
/usr/local/bin/wp spaces import_pricing "$id" --path=/var/www/html --allow-root & done; wait

Tip: Adjust batch size and count based on server capacity. For 100 assets, use 4 batches of 25 staggered at one-minute intervals. Monitor load during initial rollout and tune accordingly.


Using a Shell Script

For easier maintenance, extract the import logic into a reusable script.

#!/usr/bin/env bash
# /opt/scripts/spaces-import.sh
# Usage: spaces-import.sh <command> <batch_size> <batch_seq>

set -euo pipefail

WP="/usr/local/bin/wp"
WP_PATH="/var/www/html"
COMMAND="$1"
BATCH_SIZE="${2:-}"
BATCH_SEQ="${3:-}"

if [ -n "$BATCH_SIZE" ] && [ -n "$BATCH_SEQ" ]; then
  ASSET_IDS=$($WP spaces engrain_asset_ids --field=id "$BATCH_SIZE" "$BATCH_SEQ" --path="$WP_PATH" --allow-root)
else
  ASSET_IDS=$($WP spaces engrain_asset_ids --field=id --path="$WP_PATH" --allow-root)
fi

for id in $ASSET_IDS; do
  $WP spaces "$COMMAND" "$id" --path="$WP_PATH" --allow-root &
done

wait
echo "Completed: $COMMAND (batch_size=${BATCH_SIZE:-all}, batch_seq=${BATCH_SEQ:-0})"

Example crontab using the script:

0 9  * * * /opt/scripts/spaces-import.sh import_floor_plans 25 0
1 9  * * * /opt/scripts/spaces-import.sh import_floor_plans 25 1
0 10 * * * /opt/scripts/spaces-import.sh import_content 25 0
1 10 * * * /opt/scripts/spaces-import.sh import_content 25 1
0 11 * * * /opt/scripts/spaces-import.sh import_pricing 25 0
1 11 * * * /opt/scripts/spaces-import.sh import_pricing 25 1
15 * * * * /opt/scripts/spaces-import.sh update_unit_inventory 25 0
16 * * * * /opt/scripts/spaces-import.sh update_unit_inventory 25 1

WordPress Multisite

When SPACES is installed on a Multisite network, WP-CLI targets the main site by default. Use --url to target a specific sub-site.

Subdomain Multisite

wp spaces import_pricing 123 --url=https://property-a.example.com --path=/var/www/html --allow-root

Subdirectory Multisite

wp spaces import_pricing 123 --url=https://example.com/property-a --path=/var/www/html --allow-root

List all sites in the network:

wp site list --path=/var/www/html --allow-root

Crontab example for multiple sub-sites

# Pricing — property-a at 11:00 AM UTC
0 11 * * * for id in $(/usr/local/bin/wp spaces engrain_asset_ids --field=id --url=https://property-a.example.com --path=/var/www/html --allow-root); do
/usr/local/bin/wp spaces import_pricing "$id" --url=https://property-a.example.com --path=/var/www/html --allow-root & done; wait

# Pricing — property-b at 11:02 AM UTC
2 11 * * * for id in $(/usr/local/bin/wp spaces engrain_asset_ids --field=id --url=https://property-b.example.com --path=/var/www/html --allow-root); do
/usr/local/bin/wp spaces import_pricing "$id" --url=https://property-b.example.com --path=/var/www/html --allow-root & done; wait

Important: Each sub-site has its own database tables (wp_2_, wp_3_, etc.) and maintains its own set of Engrain assets and import history. Always verify the correct --url before scheduling imports.


Logging

Redirect cron output to a log file for monitoring and debugging.

0 11 * * * /opt/scripts/spaces-import.sh import_pricing 25 0 >> /var/log/spaces-import.log 2>&1
1 11 * * * /opt/scripts/spaces-import.sh import_pricing 25 1 >> /var/log/spaces-import.log 2>&1

Set up log rotation to prevent unbounded growth.

# /etc/logrotate.d/spaces-import

/var/log/spaces-import.log {
    daily
    rotate 14
    compress
    missingok
    notifempty
}