<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/pre-release-of-polars-2-0-wvg12z4td" -->

---
title: Pre-release of Polars 2.0 | daily.dev
description: Polars 2.0 release candidate is now available, with the streaming engine becoming the default for all LazyFrame queries, promising roughly 5x performance gains...
canonical: https://daily.dev/posts/pre-release-of-polars-2-0-wvg12z4td
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Pre-release of Polars 2.0 | daily.dev
og:description: Polars 2.0 release candidate is now available, with the streaming engine becoming the default for all LazyFrame queries, promising roughly 5x performance gains...
og:url: https://daily.dev/posts/pre-release-of-polars-2-0-wvg12z4td
og:image: https://api.daily.dev/og/posts/WvG12Z4TD.png
og:image:alt: Pre-release of Polars 2.0
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.

# Pre-release of Polars 2.0

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

## Summary

Polars 2.0 release candidate is now available, with the streaming engine becoming the default for all LazyFrame queries, promising roughly 5x performance gains and major memory improvements for most users. The major version bump also brings stricter default behavior: lossy type coercions in is_in, mismatched-length horizontal concatenation, and ambiguous casts now raise errors instead of silently producing wrong results. Removed APIs (like melt and join_nulls) now surface new AttributeRemovedError and ArgumentRemovedError exceptions pointing to replacements. A full migration guide is available, and the release candidate can be installed via pip install polars==2.0rc1.

## Full article

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

## Questions this post answers

### What changes in Polars 2.0 when calling collect on a LazyFrame?

Calling collect on a LazyFrame now defaults to the streaming engine instead of the in-memory engine, delivering roughly 5x faster performance and much lower memory usage for most queries. The tradeoff is that row order is no longer guaranteed by default for operations like join, group_by, and unpivot. Developers can opt into observable order with maintain_order=True, or revert to the in-memory engine via pl.Config.set_engine_affinity('in-memory') or collect(engine='in-memory').

_Teams planning a Polars 2.0 upgrade can track breaking engine changes like this via daily.dev._

### Why does Polars 2.0 raise an error on is_in comparisons between Int64 and Float64 series?

Polars 2.0 raises InvalidOperationError instead of silently casting Int64 to Float64 during is_in checks, because that cast can be lossy above 2^53, the largest integer float64 can represent exactly. In earlier versions, an Int64 user ID like 9007199254740993 would silently round to 9007199254740992.0 and produce a false positive match. Users must now explicitly cast to handle the lossy conversion.

_Developers debugging silent data-mismatch bugs can follow strictness changes like this on daily.dev._

### What replaced the melt method and join_nulls parameter in Polars 2.0?

The melt method was removed in Polars 2.0 in favor of LazyFrame.unpivot, with the id_vars parameter renamed to index and value_vars renamed to on. The join_nulls parameter, deprecated since version 1.24, was removed and renamed to nulls_equal. Calling the old APIs now raises typed AttributeRemovedError or ArgumentRemovedError exceptions that point to the replacement.

_Anyone migrating a Polars codebase can check API renames like these on daily.dev before upgrading._

## Community discussion

Top comments from developers on daily.dev.

**@agustinbarrientos** · 0 upvotes

> I'd run the same LazyFrame repeatedly under both engines. That can expose downstream code that accidentally treated join or group_by output order as stable.

---

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

[View this post on daily.dev](https://daily.dev/posts/pre-release-of-polars-2-0-wvg12z4td)

```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":"Pre-release of Polars 2.0","url":"https://daily.dev/posts/pre-release-of-polars-2-0-wvg12z4td","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/pre-release-of-polars-2-0-wvg12z4td"},"datePublished":"2026-09-02T12:51:51.529Z","dateModified":"2026-09-06T16:58:46.556Z","description":"Polars 2.0 release candidate is now available, with the streaming engine becoming the default for all LazyFrame queries, promising roughly 5x performance gains...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/962a3efc8033253193b43a5bd659e266?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/962a3efc8033253193b43a5bd659e266?_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":1,"discussionUrl":"https://daily.dev/posts/pre-release-of-polars-2-0-wvg12z4td","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":18},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":1}],"keywords":"python,data-engineering,polars","timeRequired":"PT7M"}
{"@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":"Pre-release of Polars 2.0"}]}
{"@context":"https://schema.org","@type":"WebPage","@id":"https://daily.dev/posts/pre-release-of-polars-2-0-wvg12z4td","comment":[{"@type":"Comment","text":"I’d run the same LazyFrame repeatedly under both engines. That can expose downstream code that accidentally treated join or group_by output order as stable.","datePublished":"2026-09-03T17:57:27.352Z","url":"https://daily.dev/posts/WvG12Z4TD#c-pJrtYLqxP","author":{"@type":"Person","name":"Agustin Barrientos","url":"https://daily.dev/agustinbarrientos","image":"https://media.daily.dev/image/upload/s--5ayxQnqn--/f_auto/v1788281802/avatars/avatar_wQYYVe5Tbj0NJ7C7qPoa8?_a=BAMAMicg0"}}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/pre-release-of-polars-2-0-wvg12z4td#faq","mainEntity":[{"@type":"Question","name":"What changes in Polars 2.0 when calling collect on a LazyFrame?","acceptedAnswer":{"@type":"Answer","text":"Calling collect on a LazyFrame now defaults to the streaming engine instead of the in-memory engine, delivering roughly 5x faster performance and much lower memory usage for most queries. The tradeoff is that row order is no longer guaranteed by default for operations like join, group_by, and unpivot. Developers can opt into observable order with maintain_order=True, or revert to the in-memory engine via pl.Config.set_engine_affinity('in-memory') or collect(engine='in-memory'). Teams planning a Polars 2.0 upgrade can track breaking engine changes like this via daily.dev."}},{"@type":"Question","name":"Why does Polars 2.0 raise an error on is_in comparisons between Int64 and Float64 series?","acceptedAnswer":{"@type":"Answer","text":"Polars 2.0 raises InvalidOperationError instead of silently casting Int64 to Float64 during is_in checks, because that cast can be lossy above 2^53, the largest integer float64 can represent exactly. In earlier versions, an Int64 user ID like 9007199254740993 would silently round to 9007199254740992.0 and produce a false positive match. Users must now explicitly cast to handle the lossy conversion. Developers debugging silent data-mismatch bugs can follow strictness changes like this on daily.dev."}},{"@type":"Question","name":"What replaced the melt method and join_nulls parameter in Polars 2.0?","acceptedAnswer":{"@type":"Answer","text":"The melt method was removed in Polars 2.0 in favor of LazyFrame.unpivot, with the id_vars parameter renamed to index and value_vars renamed to on. The join_nulls parameter, deprecated since version 1.24, was removed and renamed to nulls_equal. Calling the old APIs now raises typed AttributeRemovedError or ArgumentRemovedError exceptions that point to the replacement. Anyone migrating a Polars codebase can check API renames like these on daily.dev before upgrading."}}]}
```

