Introduction

Get an overview of the Contextual Query Language.

Contextual Query Language (CQL) is an English-based language tailored to the needs of modern digital experiences, with a strong emphasis on personalization, experimentation, and machine learning.

What makes CQL special is that it combines the simplicity of natural language with an intuitive syntax that makes it easy for both technical and non-technical users to formulate queries.

In this overview, we explore the motivation behind CQL, some of the things you can do with it, and the design principles that guide its development.

Introduction

Designed to bridge the gap between business requirements and technical implementation, CQL allows teams to focus on the "what" rather than the "how" when it comes to personalization and experimentation.

Take the example of determining a user's location. The location information can come from a variety of sources, such as IP address, GPS, user profile, or even a combination of these.

Abstracting the technical details

With CQL, resolving the user's location is as simple as typing location. The engine handles the rest — from determining the most accurate source to retrieving the information.

In other words, CQL acts as an abstraction layer to ensure that location refers to the most accurate information available, no matter where it comes from or how it is obtained. The same applies to many other use cases, such as user intention, marketing campaigns, and more.

You may be wondering why we chose to create a new query language instead of accepting free text as input. The answer lies in the inherent ambiguity of natural languages, making it difficult to guarantee the correctness of interpreted expressions, especially in sensitive areas such as user segmentation and content targeting.

In this sense, you can think of CQL as a canonical form of natural language that provides a reliable and standardized way to express queries.

This approach provides the flexibility to include a free-text interpretation layer that generates CQL queries under the hood, while giving you control over all generated queries to ensure that the interpretation matches your intent.

Use cases

As you interact with our platform, you will come across CQL frequently. That is because CQL can handle many tasks related to personalization, from making decisions to manipulating data.

Here are some of the things you can do with CQL in the platform:

We're actively working on extending CQL to unlock even more powerful capabilities. These include user-defined tests, third-party integrations, and AI-powered predictions — just to name a few.

Design principles

At the heart of CQL's design are five main principles that guide every aspect of the language, from syntax to error handling and type conversions.

Learnability

CQL is designed to be simple and easy to learn, even for people with no prior experience using other query languages.

Its natural-language syntax allows users to quickly grasp the basics and start writing expressions right away.

It also includes a rich set of task-specific constructs that allow users to quickly solve everyday problems without having to think about the underlying logic.

Predictability

CQL's design emphasizes consistency to ensure that the language behaves in a predictable way.

Some of the design choices that contribute to this objective include:

  • Strict adherence to the mathematical rules of precedence, associativity, and equivalence to ensure consistency across operations.
  • Reporting errors in unexpected situations, rather than using heuristics that could lead to unpredictable behavior.
  • Restrict type conversions to cases where the intent is clear, rather than relying on implicit conversions that could lead to unexpected results.

So overall, CQL's design favors explicitness over implicitness and feedback over guesswork.

Usability

While strictness can be beneficial in many cases, being overly strict can lead to a poor user experience. That is why, in some situations, we relax strictness in favor of convenience.

Take the following expression as an example:

user's age is greater than 30
Try in Playground

Most people expect this expression to return false when the user's age is unknown. However, without special handling, this expression would result in an error since the comparison operator requires numeric operands.

Therefore, if a logical expression involves an undefined variable, an unsupported conversion, or an invalid comparison, it will return false instead. Since it is logically incorrect to say that the opposite is true, user's age is not greater than 30 will also return false.

In some cases, CQL can even infer the intended meaning from the context. For example, it correctly interprets the expression sum of [1.1, 2.2, 3.3] rounded up as rounding up the result of the sum, rather than rounding up each number before adding them together. And just as we would expect, the result is 7.

Reliability

One of the things that makes real-time personalization so challenging is that you're dealing with information that, most of the time, is eventually consistent.

For example, a button click may affect the personalization of the following page. But how do we ensure this information is processed and available fast enough for subsequent personalization? After all, it depends on several factors beyond our control, such as the connection speed or how fast a user navigates between pages.

The engine behind CQL has several fallback mechanisms to handle these situations and ensure a smooth user experience. It also employs multiple strategies for high availability, guaranteeing that even when some of the underlying services are unavailable, it can continue operating with minimal impact on the end-user experience.

Responsiveness

High performance is a key requirement for real-time personalization, and CQL is designed to deliver just that.

In some cases, CQL queries can perform real-time evaluations with latencies under 20 milliseconds. Depending on the use case, this can be orders of magnitude faster than traditional approaches.

Some of the optimizations that contribute to this performance include:

  • Lazy evaluation of operations, which defers computation until absolutely necessary to avoid unnecessary processing.
  • Short-circuiting mechanisms that bypass computations when a result can be determined without fully evaluating all operands.
  • Pre-computation of information likely to be used in the next interaction to speed up response times.
  • Parallelization and batching, allowing simultaneous processing of multiple expressions to reduce end-to-end latency.
  • Caching of intermediate results to avoid the overhead of repeated data retrieval.
  • Runtime query optimization for faster execution with minimal or near-zero overhead.

These strategies, combined with a highly scalable and modern infrastructure, enable CQL to deliver lightning-fast response times for a superior user experience.

What is next

The following section walks you through writing and evaluating queries in the Playground. After that, you will see the various components of CQL and how to combine them to create more advanced queries.