CoursePress taking too much memory when loading courses and users list

I've got around 3000 students and 375 courses. All students have access to all courses. When loading the list of courses in the admin panel, PHP is using 2GB of memory. When loading the list of students its using nearly 4GB.

We're expecting the user and course counts to increase a lot, but this memory utilization is off the charts.

It seems that coursepress is loading all user's metadata into an array and processing it which would ean that memory usage will be (number of courses * metadata per course * number of users) which gets out of hand quickly.

I need to find a way to not need 4GB of memory when loading either the courses or users list :slight_smile:

  • Josh

    I've narrowed this issue down to two distinct issues.

    1. Student's page, pagination seems to be broken. Default should be 20 however it seems to actually 0, which loads all students. This amplifies any leaks or wasteful processing. As a workaround, I've added:
    if ($per_page==0) $per_page=20;
    to prepare_items() in CoursePress_Admin_Table_Students ./2.0/admin/table/class-students.php

    1b. Student's page, with broken pagination, will load all students metadata via WP object meta cache. This isn't a big deal for a page of 20 but if pagination is broken it loads the entire usermeta of every student into memory. With 3000 students subscribed to 375 courses each it causes my metacache to grow to 3.5gb.

    2. Courses page, displaying number of students certified oer course will load wp's meta cache with the usermeta of each student represented in the counts of each page. On my site even with pagination it takes nearly a minute and 3.5gb of memory while hammering my cpus to load that number. Loading a count like this via usermeta is horridly wasteful, I've rewritten column_certificates() in 2.0/admin/class-courses.php as such:
    public static function column_certificates( $item ) {
    global $wpdb;
    $sql = $wpdb->prepare( "SELECT COUNT(id) FROM $wpdb->posts where post_type='cp_certificate' AND post_parent=%d", $item->ID);
    $count = $wpdb->get_var( $sql );
    return($count);
    }

    This method may have caveats however it returns an instant response without abusing server resources.

    With these changes I'm able to reduce my php.ini max memory from 4GB back to 256MB and my slowest page is a few seconds rather than a minute.

    PLEASE address these issues in the next version so that I do not need to maintain local patches!

  • Nahid

    Hey Josh !
    Hope you are doing well today!

    Thank you very much for sharing your findings and workarounds with us. The developers have been notified about these. They'll be back to us with their insights and updates regarding the issue (or we'll be updating the ticket as soon as we hear back from them internally). Please note that the response time of the developers might be a bit delayed than that of the general Support staff. We really appreciate your patience and consideration regarding this.

    Kind regards,
    Nahid

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.