<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/what-every-python-developer-should-know-about-the-cpython-abi---nathan-goldbaum-l4x0dxniz" -->

---
title: What every Python developer should know about the...
description: A conference talk explains the CPython Application Binary Interface (ABI) and why it matters to Python developers who ship or depend on compiled extension...
canonical: https://daily.dev/posts/what-every-python-developer-should-know-about-the-cpython-abi---nathan-goldbaum-l4x0dxniz
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: What every Python developer should know about the CPython ABI - Nathan Goldbaum | daily.dev
og:description: A conference talk explains the CPython Application Binary Interface (ABI) and why it matters to Python developers who ship or depend on compiled extension...
og:url: https://daily.dev/posts/what-every-python-developer-should-know-about-the-cpython-abi---nathan-goldbaum-l4x0dxniz
og:image: https://api.daily.dev/og/posts/L4x0DXNIZ.png
og:image:alt: What every Python developer should know about the CPython ABI - Nathan Goldbaum
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.

# What every Python developer should know about the CPython ABI - Nathan Goldbaum

**[EuroPython Conference](https://daily.dev/sources/europython)** · 30 min read · 0 upvotes · 0 comments

## Summary

A conference talk explains the CPython Application Binary Interface (ABI) and why it matters to Python developers who ship or depend on compiled extension modules. It covers the difference between an API and an ABI, how wheel filenames encode Python version, ABI, and platform compatibility, and how the PyObject struct layout changed for the free-threaded (no-GIL) build, breaking binary compatibility with existing extensions. The talk details PEP 803's solution of making PyObject opaque and introducing the ABI3T tag, which lets a single extension wheel target both the GIL-enabled and free-threaded builds starting in Python 3.15, along with current tooling support in PyO3, Maturin, scikit-build-core, uv, and pip.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://www.youtube.com/watch?v=An8lO29SxXE>

## Questions this post answers

### Why does the free-threaded build of Python break extension modules that access PyObject struct fields directly?

The free-threaded build changes the layout of the PyObject struct from 16 bytes to 32 bytes by adding a local reference count, a shared reference count, and a per-object lock instead of relying on the global interpreter lock. Extension code that hardcodes struct offsets, such as reading a module name at byte offset 40, will read the wrong field and typically crash, because that offset now points to different data.

_Developers porting compiled extensions to free-threaded builds can track these ABI shifts as they follow CPython changes on daily.dev._

### What is the abi3t wheel tag introduced for Python 3.15 and why does it matter?

abi3t is a new compressed ABI tag introduced alongside PEP 803 that marks a wheel as compatible with both the GIL-enabled build and the free-threaded build using a single binary, regardless of PyObject's internal layout. It works because PyObject becomes an opaque struct, so extensions can no longer access its fields directly and must go through accessor functions like Py_INCREF instead of PyObject field offsets.

_Package maintainers deciding how many wheels to ship per release can weigh this abi3t shift on daily.dev._

### What is the difference between abi3 and CPython version-specific wheels for compiled Python packages?

abi3 wheels target the stable limited API and remain compatible with every Python version from the one they were built against onward, for example a cp312-abi3 wheel works on Python 3.12 through 3.14 and beyond, while version-specific wheels like CFFI's must be rebuilt for every new Python release such as 3.14. Version-specific wheels give better performance by skipping the limited API's function-call overhead but require yearly rebuilds.

_Teams deciding between limited-API and version-specific wheel strategies can compare tradeoffs like these on daily.dev._

## Similar posts on daily.dev

- [PyCoder’s Weekly](https://daily.dev/posts/pycoder-s-weekly-f3zfmwpbp) · Planet Python · 0 upvotes · 0 comments
- [A New Python Packaging Council and Other News for May 2026 – Real Python](https://daily.dev/posts/a-new-python-packaging-council-and-other-news-for-may-2026-real-python-j4ikhcce9) · Real Python · 0 upvotes · 0 comments
- [Memory Buffer Protocol \(Python Language Summit 2026\)](https://daily.dev/posts/memory-buffer-protocol-python-language-summit-2026--zjryycu7w) · Python Insider · 0 upvotes · 0 comments
- [Interview With Nathan Goldbaum](https://daily.dev/posts/interview-with-nathan-goldbaum-9cg5oriwl) · Lobsters · 0 upvotes · 0 comments

---

Tags: [#python](https://daily.dev/tags/python), [#cpython](https://daily.dev/tags/cpython)

[View this post on daily.dev](https://daily.dev/posts/what-every-python-developer-should-know-about-the-cpython-abi---nathan-goldbaum-l4x0dxniz)

```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":"What every Python developer should know about the CPython ABI - Nathan Goldbaum","url":"https://daily.dev/posts/what-every-python-developer-should-know-about-the-cpython-abi---nathan-goldbaum-l4x0dxniz","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/what-every-python-developer-should-know-about-the-cpython-abi---nathan-goldbaum-l4x0dxniz"},"datePublished":"2026-08-19T10:14:16.553Z","dateModified":"2026-09-14T09:20:54.838Z","description":"A conference talk explains the CPython Application Binary Interface (ABI) and why it matters to Python developers who ship or depend on compiled extension...","image":"https://i.ytimg.com/vi/An8lO29SxXE/sddefault.jpg","thumbnailUrl":"https://i.ytimg.com/vi/An8lO29SxXE/sddefault.jpg","isAccessibleForFree":true,"articleSection":"EuroPython Conference","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":"EuroPython Conference","logo":"https://media.daily.dev/image/upload/s--qu8RO-lH--/f_auto,q_auto/v1777800764/logos/europython?_a=BAMAMiWQ0","url":"https://daily.dev/sources/europython"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/what-every-python-developer-should-know-about-the-cpython-abi---nathan-goldbaum-l4x0dxniz","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"python,cpython","timeRequired":"PT30M","video":{"@type":"VideoObject","name":"What every Python developer should know about the CPython ABI - Nathan Goldbaum","description":"A conference talk explains the CPython Application Binary Interface (ABI) and why it matters to Python developers who ship or depend on compiled extension...","thumbnailUrl":"https://i.ytimg.com/vi/An8lO29SxXE/sddefault.jpg","uploadDate":"2026-08-19T10:14:16.553Z","duration":"PT30M","url":"https://api.daily.dev/r/L4x0DXNIZ","embedUrl":"https://www.youtube.com/embed/An8lO29SxXE"}}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"EuroPython Conference","item":"https://daily.dev/sources/europython"},{"@type":"ListItem","position":3,"name":"What every Python developer should know about the CPython ABI - Nathan Goldbaum"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/what-every-python-developer-should-know-about-the-cpython-abi---nathan-goldbaum-l4x0dxniz#faq","mainEntity":[{"@type":"Question","name":"Why does the free-threaded build of Python break extension modules that access PyObject struct fields directly?","acceptedAnswer":{"@type":"Answer","text":"The free-threaded build changes the layout of the PyObject struct from 16 bytes to 32 bytes by adding a local reference count, a shared reference count, and a per-object lock instead of relying on the global interpreter lock. Extension code that hardcodes struct offsets, such as reading a module name at byte offset 40, will read the wrong field and typically crash, because that offset now points to different data. Developers porting compiled extensions to free-threaded builds can track these ABI shifts as they follow CPython changes on daily.dev."}},{"@type":"Question","name":"What is the abi3t wheel tag introduced for Python 3.15 and why does it matter?","acceptedAnswer":{"@type":"Answer","text":"abi3t is a new compressed ABI tag introduced alongside PEP 803 that marks a wheel as compatible with both the GIL-enabled build and the free-threaded build using a single binary, regardless of PyObject's internal layout. It works because PyObject becomes an opaque struct, so extensions can no longer access its fields directly and must go through accessor functions like Py_INCREF instead of PyObject field offsets. Package maintainers deciding how many wheels to ship per release can weigh this abi3t shift on daily.dev."}},{"@type":"Question","name":"What is the difference between abi3 and CPython version-specific wheels for compiled Python packages?","acceptedAnswer":{"@type":"Answer","text":"abi3 wheels target the stable limited API and remain compatible with every Python version from the one they were built against onward, for example a cp312-abi3 wheel works on Python 3.12 through 3.14 and beyond, while version-specific wheels like CFFI's must be rebuilt for every new Python release such as 3.14. Version-specific wheels give better performance by skipping the limited API's function-call overhead but require yearly rebuilds. Teams deciding between limited-API and version-specific wheel strategies can compare tradeoffs like these on daily.dev."}}]}
```

