Frequently Asked Questions

For a step-by-step tutorial, see the Quick Start guide.

What is CQLi?

CQLi is a free, BSD-licensed command-line program that searches PGN files using the Chess Query Language (CQL), which was created by Gady Costeff and Lewis Stiller (see the official CQL website). About CQL in the Reference Manual covers the language's history, and A Brief Tour of CQL shows how a query works.

How is CQLi different from CQL 6.1?

CQLi is largely backward compatible with CQL 6.1 and can run most CQL 6.1 queries unchanged. CQLi adds many new features, including support for chess variants, imaginary position exploration, splitting output across multiple files, communicating with external programs, promoted piece tracking, unreachable position detection, running filters at the start or end of processing, and HHdbVII-specific features. CQLi also includes enhancements to many core CQL 6.1 features. The full list, including the places where CQLi behaves differently, is found in Differences Between CQL 6.1.

What is a PGN file and how does CQLi use it?

PGN (Portable Game Notation) is the standard file format for storing chess games. CQLi reads PGN files as input, evaluates your CQL query against every position in every game, and writes matching games to an output PGN file. Free PGN databases are available from Lichess, The Week in Chess, and other sources listed on the PGN Databases page.

Does CQLi work with Lichess databases?

Yes. CQLi fully supports the PGN format used by Lichess database exports at database.lichess.org. Lichess exports include over 8 billion rated games split by month and chess variant. CQLi also supports all chess variants available on Lichess.

How do I find all games with a specific checkmate pattern?

Use position filters combined with the mate filter. For example, to find all Arabian mates:

mate flipcolor flip { kh8 Nf6 Rh7 }

The flipcolor transform automatically handles both White and Black being checkmated, and flip handles all board reflections. The manual section Mating Patterns provides ready-to-use queries and discussion for over two dozen checkmate patterns.

Can an AI assistant write a CQL query for me?

Yes. Modern AI chat assistants can turn a plain-language description into a working CQL query when they are given an accurate reference to work from. CQL is a specialized language that most models have seen little of, and without a reference they tend to invent filters that do not exist. This site publishes llms-full.txt for exactly this purpose: a condensed version of the Reference Manual written for language models, covering every filter, the rules that most often trip up new queries, common mistakes, and about a hundred worked examples. llms.txt is a short index that points to it. Give the assistant the llms-full.txt URL if it can browse the web, or download the file and attach it to the conversation.

For example, a request like this:

Using https://cql64.com/llms-full.txt as your reference, write a CQLi
query that finds positions where a knight attacks both the opposing
king and queen, for either color.

should produce something like:

flipcolor piece $knight in N {
    k attackedby $knight
    q attackedby $knight
}

A few tips help get a correct query the first time:

Can CQLi detect illegal or unreachable chess positions?

Yes, with two filters. The legalposition filter checks that the placement of the pieces follows the basic rules of chess: one king of each color, no more than eight pawns per side, no pawns on the first or last rank, the side not to move is not in check, and so on. The reachableposition filter makes the same checks and then looks for evidence that the position could not have come from a real game: a pawn structure that needs more captures than the missing pieces allow, more promoted pieces than the pawns could have produced, a king or piece on a square it had no way to reach, and similar contradictions. It works from the position alone, so it runs quickly even across large databases.

When reachableposition reports a position as unreachable (that is, the filter does not match), the position is guaranteed to be unreachable, because the filter reaches that verdict only when it finds a contradiction that no legal game could get around. Some unreachable positions go undetected, though, so a position that passes is not necessarily reachable.

For example, this query finds compositions whose starting position is provably unreachable:

initial not reachableposition

CQLi used this capability to identify dozens of flawed studies in the HHdbVII endgame database. For the full list of checks each filter makes, and how to print the reasons a position was found unreachable, see The legalposition and reachableposition Filters in the Reference Manual.

How do I know what version of CQLi I have?

The -version command line option can be used to find the version number. Run it with the executable for your platform (cqli-arm64 or cqli-x86_64 on macOS, cqli.exe on Windows):

cqli -version

will yield something that looks like:

CQLi version 1.0.8 (c) Robert Gamble
Built on Oct 30 2026 with ICU4C version 78.1

Should options start with one hyphen or two?

Either form works. CQLi accepts every option with one or two leading hyphens, so -nosort and --nosort are the same option. Option names are also case insensitive, so a long option such as --skipunknownvariants can be written as --SkipUnknownVariants if that is easier to read. This applies only to the option name; arguments such as file names are used exactly as given. The Reference Manual writes multi-letter options in lowercase with two hyphens (--input) and single-letter options with one (-i), while examples elsewhere on this site sometimes use the single-hyphen form.

Why do queries with double quotes fail in Windows PowerShell?

Windows PowerShell 5.1, the version included with Windows, removes double quotes from inside a quoted argument before passing it to a program. A query such as -cql 'terminal settag("EndFEN" currentfen)' reaches CQLi as terminal settag(EndFEN currentfen) and fails with the error Attempted use of undefined variable 'EndFEN'. There are three ways around it:

Use the \" form only in Windows PowerShell 5.1. In PowerShell 7.3 or later, bash, and zsh, the backslashes reach CQLi and cause an error.

How fast is CQLi?

The speed of CQLi largely depends on the complexity of the query and the hardware on which it is run.

For relatively simple queries (like those found on the Quick Start page), CQLi processes over 80,000 games per second / 5,000,000 positions per second with 4 threads on a 2020 MacBook Air.

How can I make CQLi run faster?

There are several ways the performance of CQLi might be improved.

Process files locally

If the PGN database being processed resides on a network drive or resource, copy the file to a local hard drive before attempting to process it. Attempting to process a remote database can introduce substantial latency, significantly affecting performance.

Tweak the number of processing threads

By default, CQLi uses one processing thread per physical processor core, which is usually the best choice. On processors with a mix of performance and efficiency cores, specifying a lower value with the -threads option may improve performance. See Multi-threaded Execution in the Reference Manual for details.

Query optimization

The performance of expensive queries may be optimized by placing complex or resource-intensive checks after simpler checks so that the more expensive checks are only performed on positions that have already matched previous filters. In most cases it makes sense to place the checks that will weed out the largest number of positions first.

Some queries only need to execute once per game, such as those that just examine tag data or characteristics of the final position. In those cases it is more efficient to place the initial or terminal filter at the beginning of the query so that the rest of the query only gets executed at the starting or ending position for each game.

How can I reduce the memory used by CQLi?

By default, CQLi stores in memory each game that matches the provided query until the end of processing so that it can write games out in either the order they appeared in the source file or as specified with a sort filter. Stored games typically occupy 1-2 kB of memory which can be problematic when running queries that match a huge number of games or when the host system has limited available memory. In such cases the --nosort option may be used to cause CQLi to write matches out immediately instead of storing them in memory.

What variants does CQLi support?

CQLi supports the chess variants listed in the table below. See Chess Variants in the HTML Reference Manual for more information about how CQLi supports variants.

Variant Name Brief Description Recognized Aliases
Atomic Captures cause explosions that destroy surrounding pieces. Atom, Atomic, Atomic Chess
Chess960 Random setup of backrank pieces. Chess960, Fischerandom
Crazyhouse Captured pieces change color and may be dropped on later moves. Crazyhouse, Crazy House, House, ZH
Giveaway Lose all pieces or get stalemated to win. Captures are compulsory. Antichess, Giveaway, Give away, Giveaway Chess, Give away chess
Horde White has 36 pawns and wins by checkmating Black before all white pawns are captured. Horde, Horde Chess
King of the Hill Like standard chess but a king that makes it to a center square immediately wins the game. King of the Hill, kingOfTheHill, KOTH
Losers Lose all pieces except the king, get checkmated, or get stalemated to win. Captures are compulsory. Losers
Racing Kings There are no pawns. White and black pieces start on the first two ranks. Win by getting your king to the last rank first. Moves that would result in check are forbidden. Race, Racing, RacingKings, Racing Kings
Standard Standard chess. Chess, Classical, Normal, Standard
Suicide Lose all pieces to win. Captures are compulsory. Suicide, Suicide Chess
Three-Check Like standard chess but giving three checks to the opponent also wins the game. Three-Check, Three Check, ThreeCheck, Three Check Chess, 3-Check, 3 Check

How can I evaluate arbitrary chess positions?

Arbitrary positions can be presented to CQLi by creating a game in a PGN file having a FEN tag set to the FEN string of the desired position and a SetUp tag with a value of "1". For example:

[FEN "7k/7p/p1Pb1np1/8/4P3/3B4/PPP2P2/R3K3 w - - 0 1"]
[SetUp "1"]
{Rook Maze in 17} *

How can I get CQLi to process variation lines in my database?

By default, CQLi does not process variation lines. The -variations option can be used to cause variation lines to be processed.

How can I obtain engine evaluations for positions?

CQLi does not have builtin position evaluation algorithms but the Command Pipe feature allows CQLi to communicate with external programs written in any programming language. This feature can be used to submit positions to a chess engine to obtain such an evaluation. See Interacting with External Programs using Command Pipe for an example that uses a short Python script to obtain Stockfish engine evaluations from within CQLi.

How can I print the FENs of positions matching my query?

Add the filter message currentfen to the location within the query where you would like the FEN to be emitted.

Where can I download PGN databases?

The PGN Databases page contains sources for obtaining game and study databases.

How can I report a bug or request a feature?

Feedback about CQLi is always appreciated. Please feel free to reach out to the author of CQLi, Robert Gamble, at with questions, feedback, or feature requests.