BricksMembers is fast because it combines normalized relationship tables, derived projection tables, and request/object caching.
What to Use
- Use public API functions for levels, access, progress, and navigation
- Use batch/recompute jobs for large structural updates
- Let
brm_post_datahelper columns such asstructure_id_key,is_tracking_level, andanc_*handle structure queries - Let normalized tables handle level and completion filtering
Newer Module Query Paths
Newer modules follow the same performance contract as the original access/progress runtime: hot reads must use indexed columns, request-local caches, and batch preloading instead of repeated per-item SQL.
- Events:
BrmEventQueryServicecaches event rows, targets, and user registrations inRequestRegistry. Write services clear those maps after event or registration mutations. - Progress completed-item targets:
CompletedItemTargetReadServiceresolves the Bricks context and caches last-completed targets inRequestRegistry;ProgressTrackingReadServiceperforms the indexed read againstbrm_post_dataandbrm_user_post_completions. Do not scan_brm_parent_level_*meta or run per-card ad-hoc SQL for{brm_progress:completed_item:last}. - Payments: one-time payment offer checks use
brm_billing_payments.offer_keywhen the query-performance schema is current. Legacydata_json.offer_keyis temporary compatibility only. - Billing loops: subscription payment loops should call
BillingDataService::preload_payments_for_subscriptions()or useBillingQueryServiceso payment rows are loaded in batches. - Automations: queue reads and stale-claim release depend on indexed
status,available_at,heartbeat_at, andfailed_atcolumns. - Member Chat: room lists order by
last_activity_at, which is maintained on room writes and indexed for global, scoped, and group-scoped room lists.
What to Avoid
- Direct ad-hoc SQL against legacy JSON fields
- Repeated per-item helper calls inside loops when a batch loader already exists
- Manual writes to derived projection data outside the owning service
// Good
if ( brm_can_user_access_content_now( $user_id, $post_id ) ) {
// Render content.
}
// Good
$completed = \BaselMedia\BricksMembers\Modules\Progress\ProgressCompletionReadService::get_instance()->get_completed_post_ids_for_user( $user_id );
// Avoid
global $wpdb;
$wpdb->get_results( "SELECT ..." );