How to Search Chess Games by Position Pattern
This guide walks you through using CQLi and Chess Query Language (CQL) to search millions of chess games for specific position patterns, checkmate types, or tactical motifs.
What you need
- CQLi — free for Windows, macOS, and Linux
- A PGN chess game database — see the Resources page for free sources including Lichess
- A terminal or command prompt
Step 1: Download CQLi
Download the CQLi binary for your platform from the Downloads page. Extract the zip file to any directory — no installer is required. Verify the installation by running:
cqli -version
You should see output like CQLi version 1.0.7 (c) Robert Gamble. Note that the executable name may differ depending on your platform — for example, cqli.exe on Windows or cqli-arm64 on ARM-based macOS.
Step 2: Obtain a PGN database
You need a PGN (Portable Game Notation) file to search. Some options include:
- Lichess — free monthly exports of millions of games at database.lichess.org. Most monthly files contain 90–100 million games.
- The Week in Chess — free weekly PGN with several thousand high-quality OTB games at theweekinchess.com/twic.
- Any PGN file you already have — CQLi reads standard PGN format.
For testing, a small PGN file with a few hundred games is enough to get started. See the Resources page for more options.
Step 3: Write a CQL query
A CQL query is a plain text file with the .cql extension. The simplest queries are a single filter on one line.
For example, to find every game that ends with a checkmate delivered by an en passant capture, create a file named enpassant-mate.cql with this content:
move enpassant : mate
The move enpassant filter matches positions where the next move played is an en passant capture. The : mate makes this a speculative move filter — it evaluates the mate filter in the position that results from making that move, effectively requiring that the en passant capture delivers checkmate.
A slightly more complex example — finding all Arabian mates (king mated on a corner square by a rook defended by a knight):
mate
flipcolor flip { kh8 Nf6 Rh7 }
Here mate requires the position to be a checkmate, flipcolor handles both White and Black being checkmated, flip handles board reflections to match any corner or orientation, and the braced block specifies the exact piece configuration.
For more query examples, see the Quick Start guide and the Examples page.
Step 4: Run CQLi
From your terminal, run:
cqli -i input.pgn -o matches.pgn enpassant-mate.cql
Replace input.pgn with the path to your PGN database and matches.pgn with the desired output filename. CQLi will:
- Read every game from
input.pgn - Evaluate your query against every position in every game
- Write all matching games to
matches.pgn - Report progress and a final count of matching games
You can also pass a query directly on the command line using the -cql option:
cqli -i input.pgn -o matches.pgn -cql 'move enpassant : mate'
To limit processing to the first 100,000 games (useful when testing on a large file), add the -g option:
cqli -i input.pgn -o matches.pgn -g 1 100000 enpassant-mate.cql
Step 5: Review results
Open matches.pgn in any chess GUI — Lichess board analysis, ChessBase, SCID, or any other tool that reads PGN files. CQLi adds a {CQL} comment at the matching position in each game, so you can navigate directly to the relevant move.
For matching Lichess games with a Site tag, you can open the game directly on Lichess to see the full game with engine analysis.
Next steps
- Browse Quick Start examples for more one-line queries
- Read the Examples page for in-depth walkthroughs of complex queries
- Check the FAQs for common questions about performance, variants, and advanced features
- Consult the Reference Manual (included with the download) for the complete filter reference