Moodle custom reports with the report builder

Moodle's report builder lets administrators and report managers define their own course, user and activity reports without custom code. This page explains how it works, how to configure and secure it, and when a separate analytics stack is still needed.

On this page

How Moodle custom reports answer operational and compliance questions

A learning or compliance lead who needs the same answer every month should not have to rebuild it by hand from CSV exports. The Moodle report builder lets administrators define custom reports over data already stored in Moodle, so questions such as who has completed mandatory training, which learners are overdue for recertification, or which courses have stalled can be answered from the same source each time. Before building anything, confirm the exact sources, columns, conditions and export formats available in the documentation for your Moodle version, because the set of options has changed across releases. A custom report starts with a report source, which defines the base data set and the joins Moodle makes to related tables. The builder then lets you choose the columns to display and add conditions that filter rows, such as a course category, a completion status or a date range. Conditions can often be set as default values or left for the viewer to change when the report runs. Test each condition against a known learner before relying on it, because a filter that looks correct on a small test course can behave differently across thousands of enrolments and multiple cohorts. The teams that usually need custom reports include learning and development for completion tracking, compliance for evidence of mandatory training, course design for identifying content that learners never open, and support staff who need a standing view of enrolment problems. Scheduled delivery can send a report to named recipients on a fixed cadence, which removes a manual step. Decide early who receives each report, because scheduled reports carry learner names and results out of the platform and into email. Access control then needs the same care: confirm which Moodle roles and contexts can view, edit and schedule reports, and restrict the audience so that a manager sees only their own team. The builder covers most in-platform questions, but some needs point to a separate analytics stack. These include joining Moodle data with HR, payroll or finance records held elsewhere, keeping long historical trends beyond what the site retains, serving executive dashboards with many data sources, and running heavy queries that could slow a production site. Write down the questions you need answered each month, mark which ones depend on data outside Moodle, and check the report builder against that list before committing to either approach.

Report builder options and when each one fits

This table compares the configuration choices a team makes when building custom reports in Moodle's report builder, from source selection to scheduled delivery and access. Read each row as a decision: the typical use, the maintenance or data exposure it creates, and what to check in your local version before you commit.

OptionTypical use caseTrade-off in maintenance or exposureVerify in your local version
Report sourceChoosing a base such as courses, users, activities or completions to answer one operational questionEach source sets which personal and grading data is reachable; a broad source is easier to build but exposes more fieldsConfirm which sources are enabled on your site and which user fields each one exposes
ColumnsShowing the fields reviewers need, such as completion date, enrolment status or gradeExtra columns add joins and slow large reports; columns that hold personal data widen what a viewer seesTest column output with a large course and check that hidden profile fields stay hidden
ConditionsLimiting rows to a cohort, a category, a date range or a roleConditions are the main control on which rows appear; a loose condition can silently include learners who should be excludedRun the report as a test user in each affected group and compare row counts with a manual check
Default filtersPre-setting a filter so each viewer starts with the right slice, such as their own departmentDefaults can be changed by viewers unless the report is locked, so they guide use but do not enforce accessConfirm whether viewers can clear or change the default and whether your version offers a fixed condition
Scheduled deliverySending a weekly completion or compliance summary to a named mailbox or groupRecipients receive a copy of the data outside Moodle, so the mailbox and attachment format become part of your data exposureConfirm the scheduled task is running, the export format, and who receives it after staff leave
Viewing and editing accessLetting managers see their teams while a small admin group edits report definitionsBroad capability grants let staff edit or export data they do not own; narrow grants add upkeep as roles changeReview the capabilities granted to each role and test access as a user from each role
Custom report pluginsNeeds the core builder cannot meet, such as unusual joins or a specialized exportCustom code must be kept aligned with each Moodle upgrade and reviewed for data handlingCheck plugin compatibility with the exact Moodle version you plan to run before the build starts

How the Moodle report builder combines sources, conditions and columns

A custom report in Moodle is built from three parts that act in a fixed order. The report source defines the base records, such as users, courses or enrolments, and nothing outside that base can appear in the result. Columns then add fields from related data, so a column can show a course name or a completion date for each base record, but a column does not add rows. Conditions filter the result set, so a condition on a field changes which records survive while the column only displays a value. Before building anything, decide which source is the unit of counting, because every later choice depends on it. Confirm on your installed version which sources, columns and condition operators are offered, since the available list can change between releases.

Custom reports start from a different place than the standard reports and logs. Standard course reports are fixed views built around the questions Moodle's developers anticipated. The logs record a stream of events, which must be aggregated before they describe current state, such as whether a learner is still enrolled. The report builder lets your team choose the base records, the fields and the filters, then save the definition for reuse by others. That flexibility has a cost. A saved report is only as correct as its definition, and it will not warn you when a field it depends on changes meaning after an upgrade or a plugin change. Treat each report as a small specification with a named owner, and review it after every Moodle upgrade.

The builder joins data only along relationships that each source exposes. If the data you need lives in another system, such as an HR feed, a grading export kept in a spreadsheet or a separate analytics database, the builder cannot join it directly. A combined view then needs an integration, or the question moves to a separate analytics stack. Joins can also multiply rows. When a base record relates to several related records, such as several enrolments or several completion entries, each one can produce its own line, and a total then counts the same learner more than once. Check the row count against the source before trusting any summary, and decide whether a multi-value relationship should be collapsed by a condition, a chosen column or a separate report.

Most mismatched numbers trace back to an undefined population before the query is ever checked. Active learners, enrolled users and a cohort sound interchangeable, but each one selects different records. Enrolled users may include suspended enrolments, suspended accounts, staff holding teacher roles and learners whose enrolment has ended. Write the population as a rule with every term defined: which enrolment status counts, whether suspended accounts are excluded, which roles are removed and which date window applies. Agree that definition with the people who consume the report before the first build, so the same rule is reused in every report that reads the population.

Before anyone relies on a report, test it against a list whose status you already know. For illustration, take five to ten users from source records: an active learner, a suspended learner, a learner whose enrolment has ended, a teacher and a user with two enrolments in the same course. Run the report with the defined population and check that each known user appears or is excluded as the rule requires, and that the row count matches the count you expect. Keep the test list and its expected results with the report definition, then repeat the test after each Moodle upgrade or plugin change. A report that passes this check still needs a periodic recheck, because the data behind it keeps changing.

Setup sequence for custom reports in Moodle

This sequence takes a Moodle site from a confirmed version and enabled report builder to scheduled reports that answer agreed questions, use agreed data definitions and reach only permitted readers. Each step closes with a check, such as a comparison against a known cohort or a role-by-role access test, so the team can show the reports are correct before anyone relies on them.

  1. Confirm the Moodle version and server requirements

    Start with the platform team. Confirm which Moodle release the site runs and check it against the PHP, database and web server requirements in the release notes for that version and for any planned upgrade. For releases from 5.1 onward, confirm that the web server document root points to the public directory, since a wrong root can expose directory listings or errors. Record the Moodle version, PHP version and database engine in the change log. The step is done when the platform owner signs off the version record and the upgrade path is written down.

  2. Enable the report builder and review its settings

    A Moodle administrator opens site administration, confirms that the report builder is enabled, and reviews which report sources are available on this installation. Check whether any installed plugins add sources, because a third-party source can expose more data than the core sources do. Keep the initial configuration small so the first reports are easy to audit. The step is done when an administrator can create a test custom report on the staging site and find it in the report list.

  3. Define the reporting questions with stakeholders

    Meet the people who will use the reports, such as compliance staff, training managers and course owners, and have each of them write every question as a sentence the report must answer. An illustrative question would be which learners in a mandatory course have not completed it by a given date. Record who asks each question, how often the answer is needed and which decision it supports. Drop any question that no one will act on. The step is done when each question has a named owner and a written purpose.

  4. Agree data definitions and sources

    Before any report is built, agree what each field means. Teams often disagree about what counts as completed, active, enrolled or passed, so write the rule for each term, the Moodle report source or table it comes from, and whether the figure includes suspended enrolments or deleted users. Identify fields that hold personal data and who may see them, and align with the privacy owner. The step is done when the stakeholders sign the data definition sheet and every field on it names its source.

  5. Build the first report on a staging copy

    Build the first report on a staging copy of the production site so that conditions and columns can change without affecting live users or scheduled jobs. Add conditions that match the agreed definitions, include only the columns each question needs, and save the configuration. Refresh the staging copy from production before testing so the data reflects current enrolments. The step is done when the report runs without errors on staging and the report owner confirms that each column matches the definition sheet.

  6. Verify results against a known cohort

    Test the report output against a group whose answer is already known. Choose a small course or cohort, count the learners by hand or with a separate query, and compare the row count and sample values with the report. Repeat the check for edge cases such as suspended enrolments, learners who were unenrolled and later re-enrolled, and users holding more than one role. Log each gap, correct the condition and run the test again. The step is done when the report matches the known cohort in every test case and the test record is kept with the report.

  7. Configure role-based access and visibility

    Decide who can view, edit and export each report. Review the capabilities granted to each role and the context in which the report is available, then sign in as a test account for each role. Confirm that each role sees only the reports it is meant to see and cannot open the builder, change conditions or view columns that contain personal data. Record the result for each role. The step is done when every test account sees only its permitted reports and export options behave as the access rules require.

  8. Schedule delivery and confirm recipients

    Set up scheduled delivery only after access is confirmed, so the output reaches recipients who are already allowed to see the data. Agree the schedule, file format and recipient list with the report owner, and confirm that the scheduled tasks run on the server's cron. Send one test delivery to a small internal group and compare the file contents with the staging results. Document who receives each report, how recipients are removed and where delivery records are kept. The step is done when the test delivery arrives intact and the owner accepts the schedule.

Securing reports that contain learner data

Reports built with the report builder can expose the same learner data as the course itself, and sometimes more once columns are combined. The cards below cover who can build and receive reports, how files leave the platform, what the exports contain, how long they persist and how access is reviewed over time. Confirm capability names and defaults for your Moodle version before you configure any role.

Report roles and course permissions

Moodle's report builder separates creating, editing, viewing and scheduling reports into distinct capabilities, which are granted to roles at system or category level. Check how a report's visibility relates to the course and category permissions a viewer already holds, because a report built from a broad source can show records that the viewer could never open inside a course. Test each role with a non-administrator account and compare the results with the course view before release. Confirm the exact capability names and their defaults for your version.

Scheduled delivery outside the platform

Scheduled reports can send generated files by email to addresses that have no Moodle account, which moves learner data beyond the site's access model. Decide which external recipients are allowed, who approves each one, and whether delivery goes to a named mailbox or a shared distribution list. Confirm with your mail administrator what happens to attachments after they leave your mail system, and whether any scanning or encryption applies to them.

Minimizing personal data in columns

Every column in a report is a disclosure decision. Remove fields the recipient does not need for the stated purpose, such as dates of birth, national identifiers or free-text feedback, and prefer pseudonymous identifiers where the audience only needs to match records. Record the purpose of each report in its name or description so that a reviewer can test every column against it during periodic checks.

Auditing who receives exported files

Confirm which report views, exports and scheduled sends your Moodle version and logging configuration record, and how long those logs are kept. Maintain a register that maps each scheduled report to its recipients, file format and the business owner who approved it. Compare that register with delivery records at a set interval so that unexplained recipients or unexpected schedules are caught early.

Retaining generated report files

Exported spreadsheets outlive the report that created them when they remain in file storage, sit on a downloader's laptop or stay in recipients' inboxes. Set a retention period for each report type, decide where generated files are stored, and confirm whether scheduled delivery leaves copies on the server. Document the deletion routine, assign an owner, and test that it runs, because a retention rule without an owner rarely executes.

Reviewing access when staff roles change

Staff changes are a common source of stale report access. Add a review step to joiner, mover and leaver processes so that anyone whose role changes has report capabilities and scheduled deliveries re-checked. Reassign or stop schedules owned by people who have left, and run a recurring review of report owners, recipients and role assignments, recording the outcome of each review.

When a separate analytics stack is still needed for Moodle data

The report builder in Moodle is a good fit for operational and compliance reports drawn from one Moodle database, but it is not the right tool for every reporting need. A separate analytics stack becomes necessary when the question spans systems Moodle does not own, when history must be kept far longer or in far greater volume than the site's day-to-day reporting handles, or when the output must be shared with people who never log in to Moodle. Before you design any custom report, decide which of these cases apply, because the answer determines whether the report builder is the end of the design or only the first stage of it.

The most common trigger is cross-system analysis. A question such as whether completion rates differ by department, job grade or enrolment cohort needs HR or student information data that lives outside Moodle. The report builder can only join what is in the Moodle database, so the HR attributes must first be synchronized into Moodle user profile fields or a custom field, and that synchronization is a design decision in its own right. If the analysis also needs academic records, finance data or data from a learning record store, the work usually moves to a warehouse where those sources can be combined under one set of keys and one set of access rules.

Volume and history are the second trigger. The report builder runs queries against live Moodle tables, and its performance depends on the size of the logs, grades and completion data it must scan, the indexes present on those tables and the database server's capacity. Confirm with your database administrator how many rows the largest log and grade tables hold today, how fast they grow, how long you must retain them, and how long a representative report takes to run at peak hours. If multi-year trend reports or large statistical analyses slow the production site, that is the signal to copy the data elsewhere on a schedule instead of querying it in place.

Exporting to a separate system has real costs. An extract pipeline needs scheduling, error handling, monitoring and a way to recover from partial loads. Every copy of learner data becomes a new place where personal data must be minimized, secured, retained for a defined period and removed when a request for erasure is valid, so the privacy and records teams must sign off on what is copied. Ownership also has to be explicit: someone must be accountable for the pipeline, for the meaning of each field and for keeping the copy consistent with Moodle after upgrades change table structures. If your organization already runs an analytics platform, such as an open-source BI tool or a data warehouse, reuse it before adding another system.

Before you choose an option, ask for a written inventory of the reporting requirements, the data sources each one needs, the volume and retention figures from your own environment, and the owner of each downstream system. Those answers decide whether the report builder can serve the need on its own, whether a scheduled export to an existing warehouse is enough, or whether a broader analytics design is needed. Keep the choice vendor-neutral at this stage, and record the decision so that future reporting requests are assessed against the same criteria.

Limits to confirm before you commit to report designs

Custom reports look simple in the report builder until a site's version, plugins, data volume and upgrade path shape what they can actually show. The cards below list the constraints to verify in your own environment before report designs become a dependency for managers, auditors or scheduled deliveries.

Report sources and columns per version

The report sources, columns and conditions available in the report builder depend on the Moodle version you run, so a design that works on a test site may not exist on production. Confirm the source and column list for your exact version in the Moodle version documentation, then rebuild one representative report on a copy of your site before you promise it to stakeholders.

Data sources added by plugins

Plugins that store their own data, such as certificates, badges or local reporting tools, can add report sources, but they also tie those sources to the plugin's release cycle. Check which sources your installed plugins register, whether they are still maintained for your Moodle version, and what happens to saved reports if a plugin is removed or disabled.

Database load on large sites

Reports that join large log, grade or enrolment tables can slow the database and compete with learners during peak hours. Test the heaviest planned report against a production-sized copy of the database on your chosen PostgreSQL, MySQL, MariaDB or SQL Server version, and decide in advance which reports run on a schedule outside teaching hours.

Time zone and locale in exports

Dates in exported CSV or spreadsheet files can shift if the site time zone, user time zone and the viewing application disagree, which matters for attendance, deadline and compliance evidence. Run a test export for a user in a different time zone, confirm how the export formats dates and numbers, and record the settings that must stay fixed.

Report behavior through upgrades

Custom reports reference database fields and plugin sources that can change between Moodle releases, and some upgrades require server changes first. Before each upgrade, re-run your saved reports on a staging site built from the target version, and check the upgrade notes for removed features or renamed sources, so a scheduled report does not fail silently after go-live.

Access control for report recipients

Report access depends on capabilities and roles, and a report shared with a broad group can expose personal data beyond what the audience needs. Map who may view, edit and schedule each report, test the permissions with a non-administrator account, and confirm that scheduled deliveries go only to the intended recipients.

What drives the effort of a custom reporting project

The effort in a custom reporting project comes mostly from deciding what each report should say, not from building it in the report builder. Plan the work as five cost components. Scoping the reporting questions comes first: who needs the answer, how often, and which decision it supports. Agreeing data definitions across departments follows, because a count of active learners or overdue completions is only as useful as the rule behind it. Building and testing the reports, configuring access and scheduled delivery come next. Maintaining the reports through Moodle upgrades continues for as long as the reports are in use. For each component, ask who on your team and who on the partner side is paid for that work.

The one-time work is front-loaded. Scoping and definition workshops are where most decisions get made, and they take the most calendar time because each department must agree on the same field, filter and date range. The number of stakeholders is the largest factor that raises effort. If two departments define completion differently, the workshop load for a single report can grow quickly. Data sources outside Moodle add a second layer. Joining HR or student information system data to course data needs an agreed extract, a matching key, and a decision on whether the report builder can reach that data at all or whether a separate pipeline is needed. Confirm each external source, its owner and its refresh schedule before anyone estimates the build.

Compliance evidence requirements change the build more than the report layout does. If a report supports an audit, you need to know which users can see it, which audiences receive it, whether personal data appears in the output, and how long exported files are kept. In Moodle, access depends on the report's audience and on the capabilities held by the roles that carry report builder permissions, so every role used for reporting should be listed and reviewed. Scheduled delivery adds a further decision. Emailing a report to a mailbox outside the institution is a disclosure decision that needs its own approval. Record who approved each report definition and keep that record with the report.

Recurring work begins once the reports go live. Report review confirms that each report still answers its original question, that its sources and conditions still match how the business uses the data, and that no one has added columns exposing more personal data than intended. Access reviews repeat on the schedule your policy sets, checking audience membership and removing leavers. Upgrade checks run before each Moodle upgrade. Confirm that the report sources, columns and conditions in use still exist in the target version, and read the release notes for changes to reporting. Treat these activities as a standing part of running the reports, and agree in advance who owns them.

When you ask for a written quote, look for each component listed separately: the reporting questions in scope and the number of reports they cover, the stakeholder workshops with the departments and roles involved, the external data sources and who supplies their extracts, the testing and acceptance criteria, and the access and delivery model, including any recipients outside the organization. Ask what is excluded, such as new reports after handover, data pipelines and analytics tooling. Ask how scope changes are priced and approved, and whether upgrade checks and access reviews sit inside the fixed scope or under a recurring retainer. A quote that does not show these items is difficult to compare with an estimate from your own team.

Questions teams ask before building Moodle custom reports

Can our own team build Moodle custom reports without a partner?

Yes, many teams do. A site administrator or reporting analyst can create custom reports in the report builder, choose a report source, add columns, conditions and schedules, and share them with staff. The harder part is less about clicks and more about agreeing what each report means. Your team can usually handle simple course completion or enrollment lists with a clear owner. Consider outside help when reports must join several data sources, when results feed compliance evidence, or when no one on staff has time to test changes after each Moodle upgrade. Ask whether your team can name a data owner for every field a report uses and can keep a non-production copy for testing.

How long does a first set of Moodle reports take to define and test?

The timeline depends on the number of reports, how many sources each one touches, and how many people must approve the output. Defining a report is usually quick once the question is settled. Most of the time goes to agreeing definitions, such as what counts as completed or active, and to checking results against known learners and courses. Drivers that lengthen the work include reports that depend on custom profile fields, multiple cohorts or enrollment methods, and scheduled delivery to external recipients. Ask any provider for a written plan that lists each report, its owner, its test cases and the sign-off step, so the duration follows from that scope.

What does the institution need to provide for a Moodle reporting project?

Reporting projects depend on people more than software. You need a named data owner for each area the reports cover, such as enrollments, grades, or training records, and someone who can approve definitions in writing. You also need a test site that mirrors your production configuration closely enough to validate report sources and access rules, plus a sample of real user scenarios to check against. Confirm early who may see personal data in each report, how long scheduled files are kept, and where they are delivered. Without these inputs, reports often pass a technical check but fail when the business reads the numbers.

What makes the cost of Moodle custom reports go up or down?

Cost follows the number of reports, the complexity of their data, and the amount of verification required. Fixed-scope work is priced from a written scope, so the quote should itemize discovery, report design, build, testing, documentation and handover. Costs rise when reports need custom SQL-level logic, cross-system data, new access rules, or formal evidence for an audit. Costs fall when definitions are agreed before the build starts, when your team owns the data dictionary, and when a smaller set of reports covers the real questions. Ask whether the quote includes post-go-live support and whether any upgrade work is separate. Ongoing support is typically a separate retainer.

Do Moodle custom reports keep working after a Moodle upgrade?

Reports built on report sources and standard fields usually carry forward, but each major release can change database structures, available sources or plugin compatibility, so every upgrade needs a regression check. Moodle 5.1 requires a minimum of PHP 8.2 and PostgreSQL 15, MySQL 8.4, MariaDB 10.11 or SQL Server 2017, and sites must be on Moodle 4.2.3 or later to upgrade. Moodle 5.3 requires PHP 8.3 or later, PostgreSQL 17, MySQL 8.4, MariaDB 11.4 or SQL Server 2019, and sites must run Moodle 4.4 or later. Confirm before upgrading that each report and any custom report source still returns the same results on a copy of production, and that any report depending on a third-party plugin has a compatible version.

When should Moodle reporting move to a separate analytics stack?

Move reporting to a separate analytics stack when the reports need data from many systems, long history, heavy aggregation, or cross-platform dashboards that would slow the Moodle database or outlast its schema. The built-in report builder works well for operational lists and course-level views inside Moodle. A data warehouse with a tool such as Apache Superset or Metabase is a better fit when executives need trends across learning, HR and finance data, or when analysts need to join sources without touching the LMS. Keep the report builder for tasks that belong to course administrators. Ask whether a planned analytics stack can be fed from Moodle through a controlled export, so reporting logic lives in one governed place.

Who can see the data in Moodle custom reports?

Access to reports is controlled by Moodle capabilities and the roles assigned in each context, so the report scope should match the permissions of the people who receive it. Review who can create, edit, view and schedule reports, because a scheduled report can send personal data to an address outside the intended group. Plan for personal data minimization by excluding fields that no recipient needs, and document who approves each new field. Compliance evidence should come from documented controls and test results, which an independent auditor or certification body then evaluates. DeployOpen prepares systems, controls and evidence for those assessments but does not issue audit reports or certifications.

How DeployOpen scopes and delivers Moodle reporting

DeployOpen plans Moodle custom reports as a fixed-scope project inside infrastructure you control. We agree in writing which report sources, conditions, delivery schedules and access rules are in scope, then build, test, document and hand over the reporting work with your team.

How we scope

  • Inventory the questions each report must answer and the owners who will act on the results.
  • Map which Moodle report sources hold the required fields and where data must come from elsewhere.
  • Agree which conditions, filters and scheduled deliveries are included in the written scope.
  • Define role-based access so each audience sees only the courses, users and fields it needs.
  • Confirm with your team whether the Moodle version in use provides the report features you need.

How we build

  • Build each custom report in the Moodle report builder and test it against known sample data.
  • Check that conditions return the same results for each user role before reports go live.
  • Configure scheduled delivery and confirm recipients, timing and file formats with your team.
  • Validate that report access follows your existing course and site roles, not separate permissions.
  • Test performance on your largest courses and user populations before scheduled runs are enabled.

How we hand over

  • Document each report's source, conditions, columns, schedule and the role that can view it.
  • Record every configuration change so reports can be rebuilt after an upgrade or restore.
  • Walk your administrators and report owners through creating, editing and retiring reports.
  • Provide a checklist for reviewing report access each term or when staff roles change.
  • Agree which reporting needs should move to a separate analytics stack and document the reason.

How we support

  • Offer ongoing support and report maintenance as a retainer, separate from the fixed-scope build.
  • Retest reports after each Moodle minor release and before any major version upgrade.
  • Review scheduled delivery and access rules with your team as courses and programs change.
  • Confirm support boundaries, response expectations and change handling in the written agreement.
  • Ask any support provider to confirm how they handle reports that depend on third-party plugins.

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.