40,298
stars
+9+48+213
3,234
forks
215
watchers
16,903
prs
13,639
issues
272
releases
0
discussions
README
Documentation:
Python
-
Rust
-
Node.js
-
R
-
SQL
|
Agents:
Skill
-
MCP
|
User guide
|
Discord
Polars: Extremely fast Query Engine for DataFrames and SQL
Polars is an analytical query engine written in Rust. Write your queries with the DataFrame API, in
SQL, or mix both: they run through the same optimizer and the same engine. It is designed to be
fast, easy to use and expressive. Key features are:
- Fast: written from the ground up in Rust with multi-threaded, vectorized (SIMD) execution
- Spill to disk: Operations that exceed available RAM can spill to disk
- Expressive API: compose complex queries with powerful expressions
- Extensible: extend Polars natively with custom code through
I/O and Expression plugins
- GPU support: optionally accelerate queries on NVIDIA GPUs
- Interoperable: uses the
Apache Arrow Columnar Format for zero-copy
data sharing
To learn more, read the user guide.
Polars in action
DataFrame API
Queries are composed from expressions or SQL. This lazy query gets optimized out of the box and runs
in parallel across all available cores:
python
import polars as pl
df = (
pl.scan_parquet("orders.parquet")
.filter(pl.col("status") == "shipped")
.group_by("customer_id")
.agg(
pl.col("amount").sum().alias("total"),
pl.len().alias("n_orders"),
)
.sort("total", descending=True)
.collect()
)
SQL
python
import polars as pl
df = pl.sql("""
WITH totals AS (
SELECT customer_id, SUM(amount) AS total, COUNT() AS n_orders
FROM read_parquet('orders.parquet')
WHERE status = 'shipped'
GROUP BY customer_id
)
SELECT c.name, t.total, t.n_orders, RANK() OVER (ORDER BY t.total DESC) AS rank
FROM totals t
JOIN read_parquet('customers.parquet') c USING (customer_id)
ORDER BY t.total DESC
""").collect()
Mix both
DataFrames and LazyFrames in scope can be queried by name, and the result of a SQL query is a
regular LazyFrame, so you can switch between SQL and expressions freely:
python
orders = pl.scan_parquet("orders.parquet")
df = (
pl.sql("SELECT customer_id, SUM(amount) AS total FROM orders GROUP BY customer_id")
.filter(pl.col("total") 1_000)
.collect()
)
Read more in the SQL user guide.
Performance
Polars is very fast. In fact, it is one of the best performing query engines available, for both
DataFrame and SQL workloads. See the PDS-H benchmarks
results.
Installation
Python
Install the latest Polars version with:
sh
pip install polars
See the User Guide for more details
on optional dependencies
Compile Polars from source
If you want a bleeding edge release you should compile Polars from source. Advanced users can also
compile for maximum performance for their architecture.
This can be done by going through the following steps in sequence:
1. Install the latest Rust compiler
2. Install maturin: pip install maturin
3. cd py-polars and choose one of the folloTop issues
#20947Tracking issue for the new streaming engine95 comments · 2025-01-28#3520Support HDF5 reading/writing (with optional dependencies)51 comments · 2022-05-28#7852write_database is Significantly slower than .to_pandas().to_sql()42 comments · 2023-03-29#12165Support of vertical fold and scan37 comments · 2023-11-01#12049Improve and expand Expr.rolling()32 comments · 2023-10-26#15443Support for uint256/int25631 comments · 2024-04-02#8976Sliding window for pl.Expr.over function31 comments · 2023-05-22#3933Row-wise random sampling in LazyFrames25 comments · 2022-07-07
Latest release
Python Polars 2.1.0 py-2.1.0 2026-10-25💥 Breaking changes - Disallow mixed string \ numeric arithmetic in eager (30071) 🚀 Performance improvements - Limit the memory of buckets sorted ahead in the sort flush (30297) - Make file readers wait for spills while over the memory budget (30296) - Count unspilled frames in the memory estimate right away (30295) - Simplify more boolean expressions and drop redundant null checks (30293) - Wait for spills while over the out-of-core memory budget (30294) - Lower the default out-of-core prefetch fraction to 0.5 (30292) - Aggregate unique and n\_unique in the streaming group-by itself (30281