<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/thread-safe-iterators-fibv1drsu" -->

---
title: Thread-safe iterators | daily.dev
description: Python 3.15 adds threading.serialize_iterator and threading.synchronized_iterator to make iterators safe to share across threads. Without them, two threads...
canonical: https://daily.dev/posts/thread-safe-iterators-fibv1drsu
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Thread-safe iterators | daily.dev
og:description: Python 3.15 adds threading.serialize_iterator and threading.synchronized_iterator to make iterators safe to share across threads. Without them, two threads...
og:url: https://daily.dev/posts/thread-safe-iterators-fibv1drsu
og:image: https://api.daily.dev/og/posts/fiBV1DRsu.png
og:image:alt: Thread-safe iterators
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.

# Thread-safe iterators

**[Planet Python](https://daily.dev/sources/planetpython)** · 4 min read · 0 upvotes · 0 comments

## Summary

Python 3.15 adds threading.serialize_iterator and threading.synchronized_iterator to make iterators safe to share across threads. Without them, two threads calling next() on the same generator can raise 'ValueError: generator already executing'. serialize_iterator wraps an iterator with a lock around each call to next(), while synchronized_iterator is a decorator that applies the same wrapping automatically to a generator function. A demo shows two threads reading from a shared slow_counter generator: unwrapped, the second thread errors out; wrapped, both threads get sequential values (1 and 2) without error.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://mathspp.com/blog/threadsafe-iterators>

## Questions this post answers

### How do I make a Python generator thread-safe when multiple threads call next() on it?

Wrap it with threading.serialize_iterator, introduced in Python 3.15, which puts a lock around each call to next() so only one thread advances the iterator at a time. Without it, calling next() on the same generator from two threads simultaneously raises 'ValueError: generator already executing'. There's also a synchronized_iterator decorator to apply this automatically to a generator function.

_Developers hardening multithreaded Python code can track new 3.15 concurrency tools on daily.dev._

### What does threading.synchronized_iterator do in Python 3.15?

It's a decorator applied to a generator function that automatically wraps the resulting iterator with a lock, making it thread-safe without manually calling serialize_iterator after creating the generator. For example, decorating a slow_counter generator with @threading.synchronized_iterator lets two threads safely call next() on the same counter and each gets a distinct sequential value instead of one raising an error.

_Anyone adopting new Python 3.15 features can keep up with changes like this via daily.dev._

### Why does calling next() on the same Python generator from two threads raise a ValueError?

Generator iterators are not thread-safe by default; Python raises 'ValueError: generator already executing' when a second thread tries to advance a generator while another thread is already inside it. This happens because a generator's internal state can only be in use by one caller at a time, so concurrent next() calls from separate threads conflict.

_Debugging flaky threading errors in Python gets easier by following fixes like this on daily.dev._

## Similar posts on daily.dev

- [Exploring Asynchronous Iterators and Iterables – Real Python](https://daily.dev/posts/exploring-asynchronous-iterators-and-iterables-real-python-9rkdwe6ag) · Real Python · 1 upvotes · 0 comments
- [Python 3.15: features that didn't make the headlines](https://daily.dev/posts/python-3-15-features-that-didn-t-make-the-headlines-mni5ub3li) · Hacker News · 4 upvotes · 1 comments
- [Async support for wrapt.synchronized](https://daily.dev/posts/async-support-for-wrapt-synchronized-nfatkii7k) · Planet Python · 3 upvotes · 0 comments

---

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

[View this post on daily.dev](https://daily.dev/posts/thread-safe-iterators-fibv1drsu)

```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":"Thread-safe iterators","url":"https://daily.dev/posts/thread-safe-iterators-fibv1drsu","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/thread-safe-iterators-fibv1drsu"},"datePublished":"2026-10-29T19:53:24.247Z","dateModified":"2026-10-29T20:05:36.981Z","description":"Python 3.15 adds threading.serialize_iterator and threading.synchronized_iterator to make iterators safe to share across threads. Without them, two threads...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/71e4e1d314909afd11da5783e17ef189?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/71e4e1d314909afd11da5783e17ef189?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Planet Python","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":"Planet Python","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/eac3cc584cb043b5a242d13752bd3d0c","url":"https://daily.dev/sources/planetpython"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/thread-safe-iterators-fibv1drsu","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"python","timeRequired":"PT4M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Planet Python","item":"https://daily.dev/sources/planetpython"},{"@type":"ListItem","position":3,"name":"Thread-safe iterators"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/thread-safe-iterators-fibv1drsu#faq","mainEntity":[{"@type":"Question","name":"How do I make a Python generator thread-safe when multiple threads call next() on it?","acceptedAnswer":{"@type":"Answer","text":"Wrap it with threading.serialize_iterator, introduced in Python 3.15, which puts a lock around each call to next() so only one thread advances the iterator at a time. Without it, calling next() on the same generator from two threads simultaneously raises 'ValueError: generator already executing'. There's also a synchronized_iterator decorator to apply this automatically to a generator function. Developers hardening multithreaded Python code can track new 3.15 concurrency tools on daily.dev."}},{"@type":"Question","name":"What does threading.synchronized_iterator do in Python 3.15?","acceptedAnswer":{"@type":"Answer","text":"It's a decorator applied to a generator function that automatically wraps the resulting iterator with a lock, making it thread-safe without manually calling serialize_iterator after creating the generator. For example, decorating a slow_counter generator with @threading.synchronized_iterator lets two threads safely call next() on the same counter and each gets a distinct sequential value instead of one raising an error. Anyone adopting new Python 3.15 features can keep up with changes like this via daily.dev."}},{"@type":"Question","name":"Why does calling next() on the same Python generator from two threads raise a ValueError?","acceptedAnswer":{"@type":"Answer","text":"Generator iterators are not thread-safe by default; Python raises 'ValueError: generator already executing' when a second thread tries to advance a generator while another thread is already inside it. This happens because a generator's internal state can only be in use by one caller at a time, so concurrent next() calls from separate threads conflict. Debugging flaky threading errors in Python gets easier by following fixes like this on daily.dev."}}]}
```

