<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/polars-in-aggregate-going-from-0-19-0-to-0-20-2-xnip9u00o" -->

---
title: Polars in Aggregate: Going from 0.19.0 to 0.20.2 | daily.dev
description: A recap of notable changes in the Polars dataframe library between versions 0.19.0 and 0.20.2, covering a native async parquet reader for AWS/GCP/Azure cloud...
canonical: https://daily.dev/posts/polars-in-aggregate-going-from-0-19-0-to-0-20-2-xnip9u00o
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Polars in Aggregate: Going from 0.19.0 to 0.20.2 | daily.dev
og:description: A recap of notable changes in the Polars dataframe library between versions 0.19.0 and 0.20.2, covering a native async parquet reader for AWS/GCP/Azure cloud...
og:url: https://daily.dev/posts/polars-in-aggregate-going-from-0-19-0-to-0-20-2-xnip9u00o
og:image: https://api.daily.dev/og/posts/XniP9U00o.png
og:image:alt: Polars in Aggregate: Going from 0.19.0 to 0.20.2
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Polars in Aggregate: Going from 0.19.0 to 0.20.2

**[Polars Blog](https://daily.dev/sources/polars)** · 8 min read · 0 upvotes · 0 comments

## Summary

A recap of notable changes in the Polars dataframe library between versions 0.19.0 and 0.20.2, covering a native async parquet reader for AWS/GCP/Azure cloud storage, a new Enum data type for categorical data, Rust-based expression plugins via FFI, algorithmic speedups for rolling quantiles (O(n log k)) and SIMD-accelerated covariance/correlation, compact syntax for column expressions and filters, and new support for scanning Apache Iceberg tables.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://pola.rs/posts/polars_in_aggregrate-0.20>

## Questions this post answers

### What does the new Enum data type in Polars 0.20.0 do differently from the Categorical type?

The Enum data type, introduced in Polars 0.20.0, guarantees consistent encoding across columns or datasets by requiring predefined categories, making operations like appending or merging more efficient without re-encoding or cache lookups. Unlike the Categorical type, which infers categories and can incur performance costs, Enum raises errors for any value not in the predefined set.

_Track dataframe library releases like this on daily.dev before picking a categorical encoding strategy._

### How much faster are Polars rolling quantile functions after the 0.20.2 rewrite compared to 0.19.0?

Polars rewrote its rolling_quantile functions between 0.19.0 and 0.20.2, replacing a naive O(n·k) implementation with a median-filtering and merge-sort based algorithm achieving O(n·log(k)) complexity. In benchmarks computing rolling median over 100M rows, version 0.19.0 scaled linearly with window size and became impractically slow, while 0.20.2 scaled far better and outperformed pandas 2.1.4.

_Developers benchmarking dataframe performance follow release breakdowns like this on daily.dev._

### How do I write Rust-based user-defined functions for Polars using expression plugins?

Polars expression plugins let you compile a user-defined function in Rust and register it as an expression in the Python Polars binary, which calls it via FFI. This gives Rust-level performance with full parallelism from the Polars engine since there is no GIL locking, and grants access to the entire Rust crate ecosystem for custom business logic.

_Engineers extending dataframe libraries with native code follow updates like this on daily.dev._

## Similar posts on daily.dev

- [Release of Polars 2.0](https://daily.dev/posts/release-of-polars-2-0-84cwf427y) · Polars Blog · 2 upvotes · 0 comments
- [Announcing Polars 1.44](https://daily.dev/posts/announcing-polars-1-44-nyx9iebfn) · Polars Blog · 1 upvotes · 0 comments
- [Polars Built a GPU Hook for NVIDIA. It Works on the Apple Silicon GPU Too](https://daily.dev/posts/polars-built-a-gpu-hook-for-nvidia-it-works-on-the-apple-silicon-gpu-too-n91scp2q0) · Medium · 0 upvotes · 0 comments
- [I Rewrote a Real Data Workflow in Polars. Pandas Didn’t Stand a Chance.](https://daily.dev/posts/i-rewrote-a-real-data-workflow-in-polars-pandas-didn-t-stand-a-chance--dpixpj7fx) · Towards Data Science · 0 upvotes · 0 comments

---

Tags: [#python](https://daily.dev/tags/python), [#performance](https://daily.dev/tags/performance), [#rust](https://daily.dev/tags/rust), [#data-engineering](https://daily.dev/tags/data-engineering), [#polars](https://daily.dev/tags/polars)

[View this post on daily.dev](https://daily.dev/posts/polars-in-aggregate-going-from-0-19-0-to-0-20-2-xnip9u00o)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Polars in Aggregate: Going from 0.19.0 to 0.20.2","url":"https://daily.dev/posts/polars-in-aggregate-going-from-0-19-0-to-0-20-2-xnip9u00o","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/polars-in-aggregate-going-from-0-19-0-to-0-20-2-xnip9u00o"},"datePublished":"2026-08-16T08:53:20.716Z","dateModified":"2026-08-16T08:55:45.426Z","description":"A recap of notable changes in the Polars dataframe library between versions 0.19.0 and 0.20.2, covering a native async parquet reader for AWS/GCP/Azure cloud...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/5434e7bec80a8efdf8c46b2f6f76f432?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/5434e7bec80a8efdf8c46b2f6f76f432?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Polars Blog","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Polars Blog","logo":"https://media.daily.dev/image/upload/s--xo60W3UW--/c_limit,w_256/f_auto,q_auto/v1786870390/logos/polars?_a=BAMAMicg0","url":"https://daily.dev/sources/polars"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/polars-in-aggregate-going-from-0-19-0-to-0-20-2-xnip9u00o","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"python,performance,rust,data-engineering,polars","timeRequired":"PT8M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Polars Blog","item":"https://daily.dev/sources/polars"},{"@type":"ListItem","position":3,"name":"Polars in Aggregate: Going from 0.19.0 to 0.20.2"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/polars-in-aggregate-going-from-0-19-0-to-0-20-2-xnip9u00o#faq","mainEntity":[{"@type":"Question","name":"What does the new Enum data type in Polars 0.20.0 do differently from the Categorical type?","acceptedAnswer":{"@type":"Answer","text":"The Enum data type, introduced in Polars 0.20.0, guarantees consistent encoding across columns or datasets by requiring predefined categories, making operations like appending or merging more efficient without re-encoding or cache lookups. Unlike the Categorical type, which infers categories and can incur performance costs, Enum raises errors for any value not in the predefined set. Track dataframe library releases like this on daily.dev before picking a categorical encoding strategy."}},{"@type":"Question","name":"How much faster are Polars rolling quantile functions after the 0.20.2 rewrite compared to 0.19.0?","acceptedAnswer":{"@type":"Answer","text":"Polars rewrote its rolling_quantile functions between 0.19.0 and 0.20.2, replacing a naive O(n·k) implementation with a median-filtering and merge-sort based algorithm achieving O(n·log(k)) complexity. In benchmarks computing rolling median over 100M rows, version 0.19.0 scaled linearly with window size and became impractically slow, while 0.20.2 scaled far better and outperformed pandas 2.1.4. Developers benchmarking dataframe performance follow release breakdowns like this on daily.dev."}},{"@type":"Question","name":"How do I write Rust-based user-defined functions for Polars using expression plugins?","acceptedAnswer":{"@type":"Answer","text":"Polars expression plugins let you compile a user-defined function in Rust and register it as an expression in the Python Polars binary, which calls it via FFI. This gives Rust-level performance with full parallelism from the Polars engine since there is no GIL locking, and grants access to the entire Rust crate ecosystem for custom business logic. Engineers extending dataframe libraries with native code follow updates like this on daily.dev."}}]}
```

