Why BricksMembers Is So Fast

You might be wondering: “Why does performance even matter for a membership plugin? Isn’t WordPress already fast?”

Here’s the thing: regular WordPress sites are fast. But membership sites are different. They face a unique performance challenge that most people don’t understand until they build one.

This article explains why membership sites are inherently harder to make fast, and how BricksMembers solves this problem with optimizations that reduce database queries by up to 96% on certain pages.

The Caching Problem Nobody Talks About

Here’s the dirty secret about membership sites: they’re almost impossible to cache effectively.

Regular WordPress sites are fast because of page caching. When someone visits your blog, the server generates the HTML once, saves it, and serves that cached HTML to the next 10,000 visitors. No database queries. No PHP processing. Just instant HTML delivery.

But membership sites can’t do this.

Why? Because every user sees different content:

  • User A (Free member) sees: “Upgrade to Premium to access this course”
  • User B (Premium member) sees: The actual course content
  • User C (not logged in) sees: “Login to continue”

Same URL. Three completely different pages. You can’t cache that.

It gets worse with progress tracking:

  • User A sees: “You’ve completed 5 out of 20 lessons (25%)”
  • User B sees: “You’ve completed 15 out of 20 lessons (75%)”
  • User C sees: “You’ve completed 0 out of 20 lessons (0%)”

Same course page. Different progress for every single user. You can’t cache that either.

And drip content makes it even worse:

  • User A (joined yesterday) sees: Only Lesson 1 unlocked
  • User B (joined 30 days ago) sees: All 20 lessons unlocked
  • User C (completed Lesson 5) sees: Lessons 1-6 unlocked

Same course structure. Different unlocked content for every user based on their join date and completion status.

The result? Traditional page caching (WP Rocket, LiteSpeed Cache, Cloudflare) doesn’t help membership sites. Every page load requires:

  • Checking who the user is
  • Loading their membership levels
  • Checking their progress
  • Calculating what’s unlocked
  • Rendering personalized content

This happens on every single page load for every single user. No caching. Just raw database queries and PHP processing.

This is why membership sites are slow.

BricksMembers solves this with a different approach: we can’t cache the final HTML, but we can cache the data. And we do it aggressively, at multiple levels, with optimizations that eliminate 96% of database queries.

This article explains exactly how we do it.

The Performance Problem with Membership Plugins

Let’s talk about why membership plugins can be slow.

The Traditional Approach

Most membership plugins use WordPress’s built-in parent-child relationships and post meta to organize content. Here’s what happens when a user loads a course page:

  1. Query the post (1 query)
  2. Check user access (1 query to get user meta, 1 query to get post meta)
  3. Get the course structure (1 query per level: course → module → lesson = 3 queries)
  4. Calculate progress (1 query per completed post to check parent relationships = 50+ queries for a 50-lesson course)
  5. Check drip unlocks (1 query per post to check prerequisites = another 50+ queries)
  6. Load navigation (1 query per sibling/parent/child = 20+ queries)

Total: 150+ database queries for a single page load.

Now multiply that by 100 concurrent users and you understand why membership sites can slow down.

The Real-World Impact

In 2017, Uncanny Owl (a team that specializes in LMS optimization) documented taking a LearnDash profile page from 150 seconds load time down to 2 seconds through extensive optimization work.

BricksMembers is designed to be fast from the start, without requiring custom optimization.

How BricksMembers Achieves Extreme Performance

We use a multi-layered approach to performance, with optimizations at every level of the stack.

Layer 1: Optimized Database Tables

Think of a database like a filing cabinet. WordPress uses one giant filing cabinet (wp_postmeta) where everything is mixed together. Finding information requires opening hundreds of drawers.

BricksMembers uses separate, organized filing cabinets for different types of information:

wp_brm_post_data – One derived projection row per post

  • Stores structure paths, navigation helpers, and tracking flags
  • Keeps indexed helper columns for fast structure and boundary queries
  • One lookup = all derived structure context we need

wp_brm_user_level_assignments + wp_brm_user_post_completions – normalized relationship rows

  • Store user levels and direct completions in index-friendly tables
  • Make reporting and filtering fast even on large sites
  • Fast lookups without relying on one giant JSON payload per user

wp_brm_user_progress – Pre-calculated progress

  • Stores “User completed 15 out of 50 lessons (30%)”
  • No need to count every time someone loads a page
  • One lookup = instant progress display

wp_brm_user_unlocks – Persisted drip unlock timestamps

  • Stores “Lesson 5 unlocked for User 123 on October 15”
  • Lets BRM preserve or reuse unlocked rows without inventing a second access table
  • Combined with request cache + computed status for fast, correct unlock checks

Why This Matters:

Imagine you want to know which lessons a user completed.

Traditional plugins: Open 50 separate drawers (one per lesson) to check each one

BricksMembers: Read a small indexed set of completion rows for that user, then reuse that result throughout the request

Result: 50 lookups → 1 lookup

But Wait—Don’t Bigger Tables Slow Things Down?

You might be thinking: “If you’re storing more data in custom tables, won’t that make the database huge and slow?”

Great question. Here’s why the answer is no:

1. Indexes Make Size Irrelevant (Within Reason)

Database performance isn’t about table size—it’s about how the database finds data.

Think of it like a library:

  • Bad library: 1,000 books thrown in a pile. Finding one book = search through all 1,000.
  • Good library: 100,000 books organized with a card catalog. Finding one book = look up the catalog number, go straight to the shelf.

The good library is 100x bigger but infinitely faster because it’s indexed.

BricksMembers tables use MySQL indexes on every lookup field:

  • wp_brm_post_data: Indexed by post_id plus composite helper indexes such as structure ID + ancestor + post type
  • wp_brm_user_level_assignments: Indexed by user_id, level_id, and active-state columns
  • wp_brm_user_post_completions: Indexed by user_id + post_id
  • wp_brm_user_progress: Composite key on user_id + scope_type + scope_id
  • wp_brm_user_unlocks: Composite index on user_id + post_id

Newer BricksMembers modules use the same pattern. Events, Payments, billing taxes, Automations, and Member Chat all keep high-volume lookups on indexed columns instead of relying on broad JSON or meta scans. For example, event calendars can use indexed event dates and registration rows, one-time payment access checks use an indexed offer key, automation queues use indexed job status/date columns, and chat room lists use an indexed last-activity timestamp.

Result: Finding one user’s data in a table with 100,000 users takes the same time as finding it in a table with 100 users—about 0.0001 seconds.

2. How Traditional Plugins Store Data (And Why It’s Slow)

Most membership plugins use WordPress’s wp_usermeta table. There are two common approaches:

Approach 1: One row per completion

  • Each completion = 1 row in wp_usermeta
  • User completes 50 posts = 50 rows
  • 25,000 users × 50 = 1.25 million rows
  • Problem: Millions of rows mixed with all other user meta from every plugin

Approach 2: Serialized PHP array

  • 1 row per user with serialized array: a:50:{i:0;s:3:"123";...}
  • 25,000 users = 25,000 rows
  • Problem: Can’t query inside serialized data—must load everything into PHP and process it there

Example: “Show me all users who completed post 123”

  • Approach 1: Scan 2+ million rows in wp_usermeta → Slow
  • Approach 2: Load all 25,000 rows, unserialize in PHP, check each array → Very slow

3. How BricksMembers Stores Data (Multi-Table Architecture)

BricksMembers uses specialized tables instead of cramming everything into wp_usermeta. The important point is the separation of concerns:

Table What It Stores
brm_user_level_assignments Current and historical user-to-level assignments
brm_post_level_requirements Which levels protect each post
brm_user_post_completions Direct completion rows per user and post
brm_post_data Derived structure and access projection data
brm_user_progress Pre-computed progress per scope
brm_user_unlocks Drip unlock timestamps

Why this multi-table approach is fast:

  1. Normalized relationships: Access and completion filters hit small indexed tables directly
  2. Derived projections: Structure and progress answers are precomputed where that is cheaper
  3. Dedicated tables: No noise from other plugins, themes, or unrelated user meta
  4. Right tool for the job: Rows for relationships, generated columns for aggregates, JSON only where projection data is naturally hierarchical

Example: “Show me all users who completed post 123”

  • Traditional (serialized): Load thousands of user-meta blobs and inspect them in PHP
  • BricksMembers: SELECT user_id FROM brm_user_post_completions WHERE post_id = 123 using an index

4. Storage at Scale

At 25,000 users, BricksMembers uses ~118 MB. But what about larger sites?

Site Size Users Posts BRM Storage % of 50GB Hosting
Small 1,000 200 5 MB 0.01%
Medium 10,000 500 25 MB 0.05%
Large 25,000 1,000 118 MB 0.24%
Very Large 100,000 2,000 471 MB 0.9%
Massive 500,000 5,000 2.35 GB 4.7%
Enterprise 1,000,000 10,000 4.7 GB 9.4%

Reality check: Even at 1 million users, BricksMembers uses less than 10% of a standard 50GB hosting plan. And at that scale, you’re making millions per month—storage costs are negligible.

When Would You Actually Need More Storage?

Let’s put the real numbers in perspective across different site sizes:

Small membership site:

  • 1,000 users, 100 posts
  • BricksMembers data: ~5 MB
  • Typical hosting: 5-10 GB storage (basic shared hosting)
  • BRM uses 0.05-0.1% of your storage

Medium membership site:

  • 10,000 users, 500 posts
  • BricksMembers data: ~25 MB
  • Typical hosting: 10-20 GB storage (managed WordPress hosting)
  • BRM uses 0.125-0.25% of your storage

Large membership site:

  • 25,000 users, 1,000 posts
  • BricksMembers data: ~118 MB
  • Typical hosting: 20-50 GB storage (premium managed hosting)
  • BRM uses 0.24-0.6% of your storage

Very large membership site:

  • 100,000 users, 2,000 posts
  • BricksMembers data: ~471 MB
  • Typical hosting: 50+ GB storage (VPS/dedicated server)
  • BRM uses ~0.9% of your storage

Massive membership site:

  • 500,000 users, 5,000 posts
  • BricksMembers data: ~2.35 GB
  • Typical hosting: 100-200 GB storage (dedicated server/cloud)
  • BRM uses 1.2-2.4% of your storage

Enterprise membership site:

  • 1,000,000 users, 10,000 posts
  • BricksMembers data: ~4.7 GB
  • Typical hosting: 200-500 GB storage (enterprise cloud infrastructure)
  • BRM uses 0.9-2.4% of your storage

What actually fills up your storage?

Let’s look at a typical membership site storage breakdown:

  • Images and PDFs: 3-10 GB (featured images, course thumbnails, downloadable PDFs, worksheets)
  • WordPress core + plugins + themes: 500 MB – 2 GB
  • Database (all data): 200-500 MB
  • BricksMembers data: 50-150 MB (part of the database)
  • Backups: 3-10 GB (if stored on the same server—many hosts store backups separately)

Important: Never host course videos on your WordPress server. Video hosting platforms like Vimeo, Gumlet, and Wistia provide:

  • Adaptive streaming (adjusts quality based on connection speed)
  • Global CDN delivery (fast loading worldwide)
  • Video analytics and engagement tracking
  • DRM and security features
  • Optimized video players
  • Much cheaper storage than WordPress hosting (pennies per GB vs dollars per GB)

The reality: With videos hosted externally (as they should be), your images and PDFs use 20-100x more storage than BricksMembers data. The database (including BricksMembers) is a tiny fraction of your total storage.

The Cost Perspective

Even at massive scale, storage costs are negligible compared to revenue. Let’s look at real numbers:

Scenario 1: 100,000 users (471 MB of BRM data)

  • Your revenue: $50,000-500,000/month (at $5-50/user/month)
  • Storage upgrade needed: None (fits in standard 50+ GB hosting)
  • Extra storage cost: $0/month

Scenario 2: 500,000 users (2.35 GB of BRM data)

  • Your revenue: $250,000-2,500,000/month (at $5-50/user/month)
  • Total database size: ~3-4 GB (including WordPress core tables)
  • Storage upgrade: Maybe $20-50/month for 100-200 GB hosting tier
  • Storage cost as % of revenue: 0.001% – 0.02%

Scenario 3: 1,000,000 users (4.7 GB of BRM data)

  • Your revenue: $500,000-5,000,000/month (at $5-50/user/month)
  • Total database size: ~6-8 GB (including WordPress core tables)
  • Storage upgrade: $50-100/month for enterprise cloud infrastructure
  • Storage cost as % of revenue: 0.001% – 0.02%

Put another way:

  • If you’re making $1,000,000/month from 500,000 members…
  • …and you need to pay an extra $50/month for storage…
  • …that’s 0.005% of your revenue
  • …or $0.10 per year per 1,000 customers

The reality check:

By the time you have enough users for BricksMembers data to reach even 1 GB, you’re running a 5 to 6-figure business. At that scale:

  • You’re already on enterprise hosting (200+ GB storage is standard)
  • Your customer support costs are $10,000-100,000/month
  • Your payment processing fees are $5,000-50,000/month
  • Your email service costs are $500-5,000/month
  • An extra $50/month for storage is literally a rounding error

What you should actually worry about: Performance, not storage. A slow site loses students and costs you real revenue. BricksMembers’ approach trades a small amount of storage (that costs pennies at scale) for massive performance gains (that directly impact user retention and satisfaction).

The trade-off is worth it: Would you rather save $50/month on storage and lose $10,000/month in churn from frustrated users on a slow site? Or pay $50/month for storage and keep your users happy with instant page loads?

3. Organized Data = Faster Queries

Here’s the real performance killer: searching through mixed data.

WordPress’s wp_usermeta table (used by traditional plugins) contains:

  • User profile data (bio, description, etc.)
  • Plugin settings and preferences
  • Session tokens
  • Membership data (if using Approach 1: separate rows)
  • E-commerce data (order history, cart, etc.)
  • Social media connections
  • Everything else from every plugin

All mixed together in one giant table. Finding membership data requires filtering through millions of unrelated rows.

Example: A typical site with 25,000 users might have:

  • 2,000,000+ rows in wp_usermeta (80+ meta keys per user from various plugins)
  • Only 1,250,000 of those rows are membership completions (if using Approach 1)
  • Every query must filter through ALL 2 million rows to find the relevant ones

BricksMembers tables contain ONLY membership data.

When BricksMembers queries its own relationship tables, every row is relevant to membership logic. That lets the database use narrow, purpose-built indexes efficiently.

Example: Same site with 25,000 users:

  • wp_brm_user_level_assignments only stores level relationships
  • wp_brm_user_post_completions only stores direct completion rows
  • wp_brm_user_progress only stores aggregate scope answers
  • Queries stay fast because there is no unrelated data to scan

4. Hybrid Storage Is Efficient

You might think: “JSON in the database? Isn’t that slow?”

It depends on what you store there. BricksMembers uses JSON where the data is naturally hierarchical, and normalized rows where the data is relational.

In practice that means:

  • Rows for user levels, post requirements, and direct completions
  • Projection JSON for structure paths and related derived navigation data
  • Generated/indexed helpers so runtime queries do not have to scan JSON on every request

Example: Finding all posts in a specific structure:

  • Traditional approach: Query wp_postmeta for all posts with meta_key = 'structure_id' and meta_value = 'wordpress-mastery' → Scan millions of rows
  • BricksMembers approach: Query wp_brm_post_data by indexed helper columns like structure_id_key and ancestor IDs → Instant lookup using composite indexes

5. We Clean Up After Ourselves

BricksMembers automatically maintains database efficiency:

  • When a user is deleted: All their progress, unlocks, and data are removed
  • When a post is deleted: All references in structure paths, progress, and unlocks are cleaned up
  • When drip rules change: Old unlock records are updated or removed as needed
  • When progress tracking is disabled: Progress data can be optionally cleared

No orphaned data. No bloat. Just clean, efficient tables.

The Bottom Line on Table Size

Yes, BricksMembers stores more data than traditional plugins.

But:

  • ✅ It’s organized in dedicated tables (not mixed with everything else)
  • ✅ It’s properly indexed (instant lookups regardless of size)
  • ✅ It’s stored efficiently (JSON binary format, not separate rows)
  • ✅ It’s automatically cleaned up (no orphaned data)
  • ✅ The total size is tiny compared to your images and uploads

The result? Faster queries, not slower ones. The “extra” data we store is what makes the plugin fast—it’s pre-computed answers that eliminate expensive calculations on every page load.

Think of it like this: Would you rather do 1,000 math problems every time someone asks you a question, or write down the answers once and just read them back? BricksMembers writes down the answers.

Layer 2: Pre-Computed Structure Paths

Imagine you’re looking at Lesson 12 and want to know which course it belongs to.

Traditional approach:

  1. Check Lesson 12’s parent → finds Module 3
  2. Check Module 3’s parent → finds Course 1
  3. Now you know Lesson 12 is in Course 1

That’s 3 separate lookups just to find the course.

BricksMembers approach:

Let’s look at a 4-level structure: Course → Module → Lesson → Video

Example 1: A Video (bottom level)

{   "structure_id": "wordpress-mastery",   "ancestry_ids": {     "course": [123, 1],     "module": [456, 3],     "lesson": [789, 5]   },   "nav": {     "next_id": 791,     "prev_id": 790   } }

Translation:

  • This video belongs to Lesson 789 (and it’s the 5th video in that lesson)
  • That lesson is in Module 456 (which is the 3rd module in the course)
  • That module is in Course 123 (which is the 1st course in the structure)
  • Next video is 791, previous is 790

Example 2: A Lesson (has video posts as children)

{   "structure_id": "wordpress-mastery",   "ancestry_ids": {     "course": [123, 1],     "module": [456, 3]   },   "nav": {     "next_id": 790,     "prev_id": 788   },   "boundaries": {     "video": {       "global": {"min": 1, "max": 12},       "count": 12     }   } }

Translation:

  • This lesson is in Module 456 (which is the 3rd module in the course)
  • That module is in Course 123 (which is the 1st course in the structure)
  • Next lesson is 790, previous is 788
  • This lesson has 12 videos (positions 1-12)

Why the position numbers matter:

The second number in each pair (like [123, 1]) tells us the position within the parent. This is used for:

  • “Require ALL previous items” drip rule: If this is lesson 15, we need to know “get me lessons 1-14” (we use the position to query the first 14 items)
  • Scheduled drip: “Unlock 3 lessons every 7 days” (position 1-3 unlock immediately, 4-6 unlock after 7 days, etc.)
  • Progress calculations: When calculating percentages across boundaries

Why boundaries matter:

When you want to show “all videos in this lesson,” traditional plugins have to check every single video in your entire site to see if it belongs to this lesson. That’s slow.

BricksMembers stores the answer directly in the lesson: “Videos 1-12 belong to this lesson.” One lookup, instant answer.

Note: Only parent posts have boundaries (posts with children). Bottom-level posts (like videos in this example) don’t have boundaries because they have no children.

Result: 3+ lookups → 0 lookups (already have all the answers)

Layer 3: Three-Tier Caching Strategy

Even with organized filing cabinets, opening drawers takes time. So we use a smart caching system.

Think of it like this:

Tier 1: Your Desk (Instant)

When you’re working on something, you keep it on your desk. Need it again? It’s right there.

BricksMembers does the same thing. When we look up your progress once, we keep it in memory. Need it again on the same page? Instant.

Example: You have a progress bar at the top and a “15/50 lessons complete” tag at the bottom. We look up your progress once, then reuse it. No second lookup needed.

Tier 2: Your Bookshelf (Fast)

Some information you use often but not constantly. You keep it on a nearby bookshelf.

BricksMembers stores frequently-used data in WordPress Object Cache (Redis, Memcached, or transients). This data stays available for 15 minutes.

Example: Your membership levels don’t change often. We cache them so every page load doesn’t need to check the database.

Tier 3: The Filing Cabinet (Slow)

When you need something for the first time, you have to go to the filing cabinet.

BricksMembers only queries the database when data isn’t on your desk (Tier 1) or bookshelf (Tier 2).

Example: First time loading your membership levels → Database query → Store in Object Cache (Tier 2) and Request Registry (Tier 1) → Next time it’s instant from cache.

Layer 4: Batch Loading for Query Loops

Imagine you’re showing a page with 100 courses. Each course needs to display:

  • Progress (15/50 lessons complete)
  • Access status (locked/unlocked)
  • Drip status (available now/unlocks Oct 15)

The slow way: Check each course one by one

  • Course 1: Check progress, check access, check drip
  • Course 2: Check progress, check access, check drip
  • Course 3: Check progress, check access, check drip
  • …100 times

That’s 300+ database lookups.

The BricksMembers way: Load everything at once

Before showing any courses, we:

  1. Get the list of all 100 course IDs
  2. Load ALL progress data for these 100 courses in ONE query
  3. Load ALL access data for these 100 courses in ONE query
  4. Load ALL drip data for these 100 courses in ONE query
  5. Store everything in memory (Tier 1 cache – your desk)

Now when we display each course, the data is already there. Zero additional lookups.

Result: 300+ lookups → 3-4 lookups (up to 99% reduction in query loops)

Real-World Example:

Page with 10 courses, 299 lessons, using progress tags and drip filters:

Without batch loading: 950 database queries, ~25ms database time

With batch loading: 40 database queries, ~4ms database time

Result: 96% fewer queries, 84% faster

This is a complex page with query loops, progress tracking, and drip content. Simpler pages see smaller but still significant improvements.

Layer 5: Chunking for Large Sites

What if you have 2,000 courses? Loading all 2,000 at once could overwhelm your server.

Our solution: Break it into smaller chunks.

Instead of:

  • 1 giant query for 2,000 courses (might crash)

We do:

  • 1 query for courses 1-600
  • 1 query for courses 601-1200
  • 1 query for courses 1201-1800
  • 1 query for courses 1801-2000

Result: 4 queries instead of 2,000, and your server stays happy.

Layer 6: Pre-Calculated Progress

Imagine showing “You completed 15 out of 50 lessons (30%)”.

The slow way: Count every time

  1. Count how many lessons are in the course (1 lookup)
  2. Count how many the user completed (1 lookup)
  3. Calculate the percentage
  4. Do this every time someone loads the page

The BricksMembers way: Calculate once, store the answer

We store: “User 456 completed 15 out of 50 lessons in Course 123”

When you load the page, we just read this pre-calculated answer. No counting needed.

Even better: We let the database do the math

We only store two numbers in the database:

  • Completed count: 15
  • Total items: 50

The database automatically calculates the percentage (15 ÷ 50 = 30%) using a MySQL generated column. This means even the percentage calculation happens in the database, not in PHP, making it even faster.

When do we recalculate?

  • User completes a lesson → Update their progress for that course
  • Admin adds a lesson → Mark the course as “needs recalculation”
  • Next time someone loads the page → Recalculate and store the new answer

Result: Instant progress display, no counting on every page load, and the database does the math for us

Layer 7: Pre-Calculated Drip Unlocks

Drip content means lessons unlock based on rules:

  • “Unlock 7 days after joining”
  • “Unlock after completing Lesson 4”
  • “Unlock on October 15”

The slow way: Check the rules every time

  1. Check when the user joined
  2. Check if they completed the prerequisites
  3. Check if the date has passed
  4. Combine all the rules
  5. Do this for every lesson on every page load

The BricksMembers way: Calculate once, store the answer

We store: “Lesson 5 is unlocked for User 456”

When you load the page, we just check if this record exists. No rule evaluation needed.

When do we recalculate?

  • User completes a prerequisite → Immediately check what new lessons unlock
  • Every 12 hours → Automatic background job checks time-based unlocks (like “unlock on October 15”)
  • Admin changes drip rules → Recalculate for all users

This means users see newly unlocked content based on dates/times without having to visit the site.

Result: Instant unlock checks, no rule evaluation on every page load

Layer 8: Smart Handling of Empty Data

Here’s a tricky problem: What if a user hasn’t started a course yet?

There’s no progress data in the database. So what happens when you try to show “0/50 lessons complete”?

The slow way: Keep checking

  • Check database for progress → Find nothing
  • Show “0/50” on the page
  • Next progress tag → Check database again → Find nothing again
  • Keep checking every time

The BricksMembers way: Remember “nothing”

When we batch-load progress for 10 courses and only find data for 2, we:

  1. Store the 2 courses with real progress
  2. Create “empty” records for the other 8 courses (0/50, 0/32, etc.)
  3. Store these empty records in cache too

Now when the next progress tag asks about Course 3, we say “We already checked—it’s 0/50.” No need to check the database again.

Result: One batch lookup instead of repeated “is there data?” checks

Why This Matters for Membership and LMS Sites

Performance isn’t just about bragging rights. It directly impacts your business.

User Experience

Slow sites lose students.

Studies show that 53% of mobile users abandon sites that take longer than 3 seconds to load. For online courses, where users are already fighting distraction, every second counts.

BricksMembers is designed to keep pages loading quickly, even with progress bars, drip unlocks, and navigation elements.

Hosting Costs

Slow plugins require expensive hosting.

When a plugin makes hundreds of database queries per page, you need powerful servers to handle the load. This can mean expensive dedicated hosting.

BricksMembers’ efficient database design and optimizations at every stage means you can run larger sites on standard managed WordPress hosting.

Scalability

Slow plugins hit walls.

As your membership site grows, inefficient plugins slow down. What worked fine with 100 users becomes unusable with 1,000 users.

BricksMembers is designed to scale. The same optimizations that make it fast for 100 users keep it fast as you grow.

Admin Productivity

Slow admin pages waste time.

When your admin dashboard takes 30 seconds to load, you waste time just waiting for pages to render.

BricksMembers admin pages are optimized to load quickly, even with large amounts of content.

For intensive operations, we show progress bars

When you make changes that require background processing (like updating drip rules or reordering content), we show a real-time progress bar so you always know something is happening. No more wondering if the page froze or if it’s still working.

We use cron keepalive to ensure slow servers can handle it

Our background workers use a “keepalive” system that nudges WordPress cron to keep processing. This ensures that even on slower shared hosting, long operations complete successfully without timing out.

Automatic performance adjustments

BricksMembers automatically detects your server’s performance and adjusts batch sizes accordingly:

  • Weak servers (shared hosting): Smaller batches, longer intervals
  • Average servers (managed WordPress): Balanced settings
  • Good servers (VPS/dedicated): Larger batches, faster processing

This means the plugin works efficiently on any hosting tier, from budget shared hosting to enterprise servers.

Real-World Performance Metrics

Here are actual measurements from a test site with 10 courses and 299 lessons, measured using BricksMembers’ built-in query counter:

Page with query loop showing 10 courses + progress tags + drip filters:

Metric Without Batch Loading With Batch Loading Improvement
BRM Queries 950 40 96% reduction
Database Time ~25ms ~4ms 84% faster

Note: The 950 baseline includes the snapshot system. The batch loading optimization specifically targets query loops with progress and drip features.

Individual course page with progress bar:

Metric Before After Improvement
BRM Queries ~25 ~3 up to 88% reduction
Database Time ~8ms ~1.5ms up to 81% faster

Simple membership page (access check only):

Metric Before After Improvement
BRM Queries ~5 ~2 up to 60% reduction
Database Time ~2ms ~0.8ms up to 60% faster

Performance varies by page complexity:

  • Pages with query loops showing many posts: up to 96% reduction
  • Pages with progress tracking and drip content: up to 88% reduction
  • Simple access-protected pages: up to 60% reduction
  • Pages without BRM features: No queries (nothing to optimize)

How to Maximize Performance

BricksMembers is fast by default, but you can make it even faster:

1. Enable Object Caching

Install Redis or Memcached on your server. This moves the object cache from database transients to in-memory storage.

Impact: Faster cache lookups (data retrieval from memory instead of database)

How to enable:

  • Ask your host to enable Redis (most managed hosts offer this)
  • Install the Redis Object Cache plugin
  • Activate it

2. Enable Batch Loading in Query Loops

Enable Batch Loading is available on Bricks loop elements. BRM applies batch loading only when that checkbox is enabled and at least one effective preload target, such as progress or drip data, is active for the loop.

If you’re using a query loop with BricksMembers dynamic tags or query filters, turn this on when the loop renders repeated progress, drip, access, or boundary-aware output.

How to enable:

  1. Edit your query loop element in Bricks – ensure query loop is turned on!
  2. In the Content Tab, find the BricksMembers section
  3. Check “Enable Batch Loading”
  4. Save

Impact: Up to 96% query reduction in query loops with progress and drip features (based on test with 10 courses and 299 lessons)

Note: The checkbox is a loop-level control. Query filter settings do not automatically turn it on by themselves.

3. Keep WordPress and Plugins Updated

Update regularly. We continuously optimize BricksMembers with each release.

Impact: Incremental performance improvements with each update

Performance Monitoring

BricksMembers includes a built-in query counter to track performance in real-time.

How to enable:

  1. Go to BricksMembers → Benchmark
  2. Open the Query Counter tab
  3. Check “Enable Query Counter (Frontend)”
  4. Click “Save Settings”
  5. Visit any frontend page as admin

You’ll see a floating box in the bottom-right corner showing:

  • Number of BRM database queries
  • BRM database time
  • Total WordPress queries
  • Percentage of queries from BRM

Use it to:

  • Verify optimizations are working
  • Identify slow pages
  • Compare before/after when making changes
  • Demo performance to clients or in videos

The Bottom Line

BricksMembers is fast because we’ve optimized every layer of the stack:

  1. Custom database tables optimized for membership data
  2. Pre-computed structure paths eliminate recursive queries
  3. Three-tier caching (Request Registry → Object Cache → Database)
  4. Snapshot system pre-loads data per boundary for instant access
  5. Batch loading loads all query loop data in 3-4 queries instead of hundreds
  6. Smart progress calculation only recomputes when needed
  7. Computed drip status with persisted unlock reuse keeps unlock checks both fast and correct
  8. Empty placeholders prevent unnecessary re-queries

The result? A membership and LMS plugin that’s significantly faster than traditional solutions, scales to tens of thousands of users, and runs on standard hosting.

You don’t need a dedicated server. You don’t need to hire a performance consultant. You just need BricksMembers.

Want to see it in action? Install BricksMembers and enable the query counter. On complex pages with query loops, you’ll see database queries drop from 950+ to 40—a 96% reduction.

Use the query counter on real pages when you want to verify that those optimizations are active on your own site.

Get BricksMembers

Start Building Your Membership Site Today

Create, sell, and manage your content without limits. BricksMembers gives you everything you need to build membership and LMS sites with Bricks Builder.

Lifetime updates & bug fixes • Premium support • 0% transaction fees • 60-day money-back guarantee