CQEngine lets Java applications query in-memory objects with typed, SQL-like predicates and indexes. The basic workflow is to create an IndexedCollection, add indexes for the queries you expect to run, insert objects, and call retrieve to get an iterable ResultSet.
It is comparable to LINQ in the way queries are expressed, but “only faster” is not a universal guarantee: CQEngine’s performance advantage depends on suitable indexes, query shape, and workload. Its published benchmarks are synthetic, single-threaded measurements.
What CQEngine does—and how it differs from LINQ
CQEngine (Collection Query Engine) is a Java library for querying objects held in memory. Its typed predicates include operations such as equality, comparisons, and Boolean combinations, while indexes can help locate matching objects without testing every object in a collection.
The LINQ comparison is useful for understanding the query style, not as a blanket performance claim. The CQEngine project contrasts indexed retrieval and set-theory operations with LINQ-style collection queries that are evaluated by iteration and filtering. The benefit therefore depends on the indexes you build and the predicates you use. See the official CQEngine README and examples.
Build a collection, index it, and retrieve results
The project’s car example illustrates the core pattern: define attributes for the object fields you query, add appropriate indexes, insert objects, then retrieve and iterate the matching results. The code below is a sketch of that workflow; the attribute definitions, imports, and complete example are in the project README.
IndexedCollection<Car> cars = new ConcurrentIndexedCollection<>();
cars.addIndex(NavigableIndex.onAttribute(Car.CAR_ID));
cars.addIndex(ReversedRadixTreeIndex.onAttribute(Car.NAME));
cars.add(new Car(1, "ford focus", "great condition", features));
Query<Car> q = or(endsWith(Car.NAME, "vic"), lessThan(Car.CAR_ID, 2));
try (ResultSet<Car> results = cars.retrieve(q)) {
results.forEach(System.out::println);
}
- Create an indexed collection.
ConcurrentIndexedCollectionis one documented option. Choose the collection and storage approach appropriate to your application. - Add indexes before querying. Indexes are defined against attributes of the objects, so identify the fields and predicate types your application will query.
- Add your objects. The collection holds the objects being queried and maintains its indexes as collection contents change.
- Build a typed query. Use predicates from
QueryFactory, such as comparisons and Boolean operators. - Retrieve and consume results.
retrievereturns a lazyResultSet; iterate it or use its stream support. Close it when finished, as shown in the example.
Choose indexes to match the predicates
An index is useful when it matches the work the query asks the collection to do. CQEngine documents several index types for common query patterns:
Rank #2
| Query pattern | Index to consider | Important qualification |
|---|---|---|
| Exact equality or key lookup | HashIndex |
Use UniqueIndex when the indexed key is guaranteed to be unique. |
| Ordered values or ranges | NavigableIndex |
Appropriate for comparable attributes and predicates such as less-than. |
| Text prefix searches | ReversedRadixTreeIndex |
Choose it for the documented prefix-search pattern; confirm its exact semantics against the API for your query. |
| Substring searches | SuffixTreeIndex |
Intended for contains-style text searches. |
| Recurring complex predicate | StandingQueryIndex |
Useful when the same complex query is executed repeatedly. |
Predicates can be combined with and, or, and not. Indexing every possible attribute is not automatically beneficial: index choice affects memory use and collection update work as well as retrieval. Measure with the actual data and query mix.
What the published benchmarks show
The CQEngine benchmark page describes a synthetic catalogue of 100,000 Car objects and single-threaded retrieval on one 1.8 GHz CPU core. It reports these workload-specific results:
| Operation measured | Published result |
|---|---|
UniqueIndex lookup |
2,967,359 queries per second; 0.337 microseconds per query |
HashIndex query returning 10,000 matching models |
4,341 queries per second; 230.361 microseconds per query |
SuffixTreeIndex substring query |
3,053 queries per second; 327.574 microseconds per query |
These figures are not a direct comparison against every Java collection, Stream pipeline, or database, and they do not establish a universal speedup. The benchmark documentation warns that microbenchmark results are useful mainly for relative latency comparisons, with caveats, and that absolute latency in production is likely to be higher. Its full-result iteration can also be more work than an application that stops after paging or finding its first match. Treat the figures as evidence about those specific synthetic workloads, not as a forecast for your application. See the CQEngine benchmark documentation.
When CQEngine fits better than alternatives
CQEngine is a candidate when the data is already in the Java process and the application repeats queries often enough to justify indexes. Before choosing it over iteration, Java Streams, or a database-backed query, compare the dimensions that matter to the workload:
Rank #4
- Latency and throughput: benchmark representative queries and result sizes, not just a single-key lookup.
- Memory and index build cost: indexes consume resources and have to be created and maintained.
- Update cost: frequent writes can change the trade-off that makes indexed reads attractive.
- Query and ordering needs: confirm supported predicates and whether result ordering meets application requirements.
- Persistence and concurrency: determine what storage and isolation behavior the application requires.
- Operational complexity: weigh managing an in-process indexed collection against the capabilities and operations of a database.
If durable storage, distributed query execution, or database-grade transactional persistence is the primary requirement, a database is generally the more appropriate system boundary. CQEngine’s documented persistence options do not by themselves make it equivalent to a database service.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Concurrency, storage, and ORM integration
The project documents ConcurrentIndexedCollection, ObjectLockingIndexedCollection, and TransactionalIndexedCollection, as well as on-heap, off-heap, and disk persistence options. These choices have different concurrency and storage implications; select one based on the application’s requirements and verify its behavior for the chosen indexes and persistence configuration.
Recommended Free Tools
Best Value
CQEngine also describes integration with Hibernate, JPA, and other ORM frameworks, where entity objects are exposed in Java collections. That makes it possible to query in-process entity objects, but does not remove the need to consider the ORM’s own loading behavior or the lifecycle and freshness of those objects.
Choose the artifact for your Java version
Artifact coordinates and maintenance status depend on which CQEngine distribution you choose. The original project README records version 3.6.0 as current in January 2021 and identifies Maven Central as its distribution channel. CQEngine Next documents a maintained fork targeting Java 21 and later, with different coordinates. Check the project pages for current release status before adding a dependency.
| Distribution | What the cited project information says | What to verify |
|---|---|---|
| Original CQEngine | README lists com.googlecode.cqengine:cqengine; version 3.6.0 was identified as current in January 2021. |
Check Maven Central and the project README for the version and compatibility relevant to your build. |
| CQEngine Next | The fork documents Java 21+ and Maven coordinates io.github.msaifasif:cqengine:1.0.0. |
Confirm current coordinates and release status, then test API and persistence compatibility in your application. |
The original project’s release notes say official compatibility was extended to Java 8, 9, and 10, while Java 6 and 7 compatibility was dropped. For Java 21 deployments, assess CQEngine Next separately rather than assuming compatibility or API parity with the original project.
Quick Recap
Sources
- CQEngine project README
- CQEngine benchmark documentation
- Original CQEngine artifact on Maven Central
- CQEngine Next project
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

