Conversations from the SideFrontlines: Get Ready for CQL to Change the Game


Measuring clinical quality is not a new concept. Measuring it automatically, using data stored in an EHR, is. Over the last several years, electronic clinical quality measurement has gone through a number of changes. Perhaps the most significant is the current push to harmonize electronic standards for quality measurement with standards for clinical decision support. There are a number of overlaps between the two domains and having a harmonized, common set of standards not only makes sense, but reduces the implementation burden on the community.


The Clinical Quality Language (CQL) is a new expression language that defines logic for quality artifacts. With its introduction into Electronic Clinical Quality Measures (eCQM), the industry has taken the first step towards a harmonized standards landscape.


The use of CQL is a big change for clinical quality measure authors. The shift changes the authoring paradigm, requiring measure authors to work more like programmers than writers. While this is intimidating, there are many long-term benefits.


eCQMs currently rely on the Quality Data Model (QDM) for data elements and operators to define data and logic. Over the years, QDM added features to meet the needs of measure developers. Although adequate, QDM has a number of weaknesses. Complex logic is difficult to define accurately and succinctly. Most people find that the logic is difficult to read and parse. Sharing of logic across measures is hard, if not impossible. These issues result from QDM’s design as a data model, first and foremost, not a full-featured expression language, like CQL.


CQL, in contrast, is a language designed to express logic for eCQMs, decision support events, order sets – you get the idea. CQL replaces the expressions and operators from QDM with a full featured language. It is more flexible, expressive, and powerful. And because it is data model agnostic, we can continue to use the data model side of the QDM (ironically, in line with its original intention). This upgrade comes with a price: time and effort on the part of measure authors learning a new method of authoring.


eCQMs combine data and logic to analyze and assess quality of care. They closely resemble simple computer programs. With CQL, measure authors will need to think and work like programmers. The constructs of the language introduce concepts found in modern programming languages, like code reuse. This allows measure developers to write pieces of logic to use across many measures through a “library” of logic.


Let’s take a look at a simple example. I am using the initial patient population (IPP) from CMS 146: Appropriate Testing for Children with Pharyngitis. Here’s the description of the IPP in plain English:

Children 2-18 years of age who had an outpatient or emergency department (ED) visit with a diagnosis of pharyngitis during the measurement period and an antibiotic ordered on or three days after the visit.


Here’s the IPP represented in QDM:

  • AND: Age >= 2 year(s) at: “Measurement Period”
  • AND: Age < 18 year(s) at: “Measurement Period”
  • AND: “Occurrence A of Encounter, Performed: Ambulatory/ED Visit” during “Measurement Period”
  • AND: “Medication, Order: Antibiotic Medications for Pharyngitis” <= 3 day(s) starts after start of “Occurrence A of Encounter, Performed: Ambulatory/ED Visit”
  • AND: Union of:
    • “Occurrence A of Diagnosis, Active: Acute Pharyngitis” satisfies any
      • starts during “Occurrence A of Encounter, Performed: Ambulatory/ED Visit”
      • satisfies all
        • starts before or concurrent with start of “Occurrence A of Encounter, Performed: Ambulatory/ED Visit”
        • ends after or concurrent with end of “Occurrence A of Encounter, Performed: Ambulatory/ED Visit”
    • “Occurrence A of Diagnosis, Active: Acute Tonsillitis” satisfies any
      • starts during “Occurrence A of Encounter, Performed: Ambulatory/ED Visit”
      • satisfies all
        • starts before or concurrent with start of “Occurrence A of Encounter, Performed: Ambulatory/ED Visit”
        • ends after or concurrent with end of “Occurrence A of Encounter, Performed: Ambulatory/ED Visit”

I know this looks complex, but we can ignore the details of the logic. Notice in QDM, the entire IPP is written as one big chunk of logic statements, combined by “AND” operators.


Here is the equivalent logic in CQL:

1   include Common version '1' called Common

2     define InDemographic:
3       AgeInYearsAt(start of MeasurementPeriod) >= 2
4         and AgeInYearsAt(start of MeasurementPeriod) < 18

5     define Antibiotics:
6       ["Medication, Order": "Antibiotic Medications"]

7     define Pharyngitis:
8       ["Diagnosis, Active": "Acute Pharyngitis"] union ["Diagnosis, Active": "Acute Tonsillitis"]

9     define MeasurementPeriodEncounters:
10       ["Encounter, Performed": "Ambulatory/ED Visit"] E
11         where Interval[E."start datetime", E."stop datetime"] during MeasurementPeriod
12         and InDemographic

13     define PharyngitisEncountersWithAntibiotics:
14       MeasurementPeriodEncounters E
15         with Pharyngitis P such that Common.includesOrStartsDuring(P, E)
16         with Antibiotics A such that A."signed datetime" 3 days or less after E."start datetime"

17     define InitialPopulation:
18       PharyngitisEncountersWithAntibiotics


In CQL, the same logic is broken into smaller pieces, (beginning with the word define, called queries), and combined later to form the IPP on line 17. The end result is the same as QDM, but the CQL approach reuses those define queries in other parts of the measure. If written as part of a library, those queries can be shared outside the measure.


In the function named PharyngitisEncountersWithAntibiotics, there is an example of both local and inter-measure code reuse. On line 16:

with Antibiotics A such that…


This is an example of local code reuse. Antibiotics is a query that is defined previously in line 6 in the above snippet. When we want to reuse the previously defined query, we use the with statement, followed by the name of the query, without rewriting the entire logic. In fairness, this is possible in recent versions of QDM as well, but is nowhere near as flexible as CQL.


Now let’s take a look at an example of inter-measure code reuse. On line 15:

… Common.includesOrStartsDuring(P, E)


This is an example of reuse via a library, where the function includesOrStartsDuring is being used from the Common library. In software programming, libraries are usually a collection of functions related to a similar theme or purpose. For example, functions defining various demographics for patients can be made into a library. This saves the author from duplicating the demographics function shown on lines 2-4 in multiple eCQMs. Once a library of functions has been defined, it can be used in any eCQM by referencing the library name. Common is one such user-defined library of functions referenced by this eCQM (in the code snippet on Line 1). One function in Common is includesOrStartsDuring, which  is being used in the code snippet on line 19. includesOrStartsDuring is a function defining a timing relationship between any two events (in this case Pharyngitis and Encounters).


If we can imagine QDM as a hand tool, then CQL is the power tool. It serves the same purpose but, in skilled hands, provides efficiencies and expressiveness that QDM cannot. Just like the shift to a power tool, however, the user needs to be retrained to make the effective use of its features. 


Thus far, measure authors have used the Measure Authoring Tool’s interface to construct measures. It offers a point-and-click approach that shields authors from writing logic by hand. CQL, with its larger feature set and expression library, does not lend itself well to that point-and-click approach. It will require a new approach and methodology that closely resembles software programming.


Measure authors see a radical shift between these methodologies. Those familiar with programming see it as an evolutionary shift. It is the equivalent of baking a cake using only store-bought ingredients, to making one from scratch. It is a different approach and there is a definite learning curve associated, but the fundamental concepts don’t change. Users get a higher quality product that isn’t possible with the previous approach. We’ll explore this concept further in future posts.


The advent of CQL may seem like an upheaval for measure authors, but it offers many long-term benefits. Measure authors can use CQL’s features to simplify measure logic, reduce the maintenance burden, and write accurate and succinct logic. Rather than being restricted to writing and maintaining logic for one measure at a time, authors can begin reusing logic, methods, and data chunks, which form population definitions across measures. Once the critical mass of code reuse is achieved, the increased efficiency and reduced effort will be well worth the effort.


Measure authors, I invite you to don the measure programmer cape. You’re going to love it.