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:
- Say exactly what should match: a position or a whole game, which side, and whether either color counts.
- Ask the assistant to explain each line of its query. An explanation that does not match what you meant is the quickest way to spot a wrong query.
- Try the query on a small part of your database first, using the
-goption (for example,-g 1 1000), and check the positions CQLi marks with aCQLcomment. - If CQLi reports an error, paste the full message back to the assistant. CQLi diagnostics give the line and column of the problem.
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 reachablepositionCQLi 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:
- Type each double quote inside the query as
\", as in-cql 'terminal settag(\"EndFEN\" currentfen)'. - Save the query in a file with a
.cqlextension and name the file on the command line instead of using-cql. - Use PowerShell 7.3 or later, which passes the quotes through unchanged.
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.