Library / SDK
rayon-rs/rayon avatar
rayon-rs/rayon

Rayon 1.12: one method name changes the schedule, and wasm quietly drops to one core

Rayon: A data parallelism library for Rust

13,466 stars629 forksRustApache-2.0

At a glance

What is it?
Rayon is a Rust library for turning sequential iterators into parallel ones, guaranteeing data-race freedom and dividing work across tasks on its own. The catch surfaces at the edges: side effects can reorder, WebAssembly falls back to sequential execution by default, and the crate floor is rustc 1.85.
Who is it for?
Use Rayon when the work divides along a collection you already own and the results can be recombined, since the iterator path handles scheduling for you. Look elsewhere when the order of side effects matters, when you are targeting the browser and have not budgeted for a threading adapter, or when your toolchain sits below rustc 1.85.0.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 18 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • rayon-rs/rayon13,466 ★ · +139
Star history
Repository2026-09-222026-11-14
rayon-rs/rayon13.3k13.5k

139 Stars in the last 53 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

One method name changes the schedule, and Rayon keeps the task boundaries to itself

The whole pitch fits in one diff. You take a sequential iterator and call the parallel version instead:

rust
use rayon::prelude::*;
fn sum_of_squares(input: &[i32]) -> i32 {
    input.par_iter() // <-- just change that!
         .map(|&i| i * i)
         .sum()
}

The iterator then decides how to divide your data into tasks, and it adapts the split dynamically rather than using a fixed chunk size. That is the appeal and the constraint at the same time. What this cannot give you is control over where one task ends and the next begins, so anything that depends on the shape of the work rather than its result has to be expressed differently: if a batch needs its own identifier, or a file needs one write per chunk, that grouping does not exist as something you can observe from inside the parallel iterator. The consequence is that the reliable unit of grouping in Rayon code is the index you already have, not the partition Rayon chose. For computations that do not sit on a sequence at all, the project points at the join and scope functions, which let you create parallel tasks yourself, and at custom thread pools for the cases where the default global pool is not what you want.

Data-race freedom is a compile-time promise, but side effects still come out in a different order

The safety claim is specific. Every Rayon API guarantees data-race freedom, which the project says generally rules out most parallel bugs, though not all, and the practical form of that claim is that if your code compiles it typically does the same thing it did before. For parallel iterators in particular, the results are meant to match the sequential counterparts. The caveat is side effects: if the iterator sends values to other threads through a Rust channel or writes to disk, those effects may occur in a different order than the sequential version produced. What that rules out is any loop whose correctness depends on the order it happened in, including code that assumed a single writer per file or that relied on a channel consumer seeing items in sequence. The consequence is that porting a sequential loop means deciding where the ordering requirement actually lives. Collect results and merge them afterwards, or funnel writes through one sink, rather than letting the loop decide. There is a second, quieter difference in the same paragraph: in some cases parallel iterators offer alternative versions of sequential iterator methods with higher performance, so the method set is not a literal mirror of the standard library and the one-word edit can need a second edit.

A custom thread pool replaces the global one rather than adding to it

There are three levels of control, and they are worth separating before you pick one. Parallel iterators give you the least: they schedule for you. The join and scope functions sit in the middle and let you create parallel tasks on your own, which is the level to use when the work is a tree, a recursive search, or anything that is not a flat sequence. Custom thread pools are the top level, and the framing matters, because the project describes them as an alternative to Rayon's default global thread pool rather than an addition to it.

WebAssembly falls back to sequential execution, and web_spin_lock only applies to one target

The browser is where this library quietly changes its behavior. By default, when building to WebAssembly, Rayon treats the platform as one without multithreading support and falls back to sequential iteration. The good news is that existing code compiles and runs with no changes necessary. The bad news is in the next sentence: it will run slower, because it uses only a single CPU core. What the default cannot do is use the cores you shipped the binary for, so a WebAssembly build that passes its tests tells you nothing about parallel behavior on the web. Getting real threading there takes an adapter plus project configuration to account for the differences between WebAssembly threads and threads elsewhere, and the project points at the wasm-bindgen-rayon docs for the details. The Cargo.toml adds one more lever, a feature called web_spin_lock that switches to a spin-lock implementation on the browser's main thread to avoid the forbidden atomics.wait, and its comment restricts it to the wasm32-unknown-unknown target. The consequence is that this flag is meaningless anywhere else, so it belongs in a wasm-specific profile rather than in a shared feature set, and enabling it does not by itself give you workers.

rustc 1.85 is the floor, and the dependency versions are held back on purpose

Rayon currently requires rustc 1.85.0 or greater, and the workspace matches that with rust-version set to 1.85 and edition 2024. Adding it to a project is one table entry:

toml
[dependencies]
rayon = "1.12"

The parallel iterator APIs also need their traits in scope in every module that uses them, which the prelude handles:

rust
use rayon::prelude::*;

What that version pair cannot do is accommodate an older toolchain, so a project still on an earlier compiler has to move Rust before it can move Rayon. The dependency set shows the same constraint from the other side, with a comment stating that some dependencies may not be at their latest version in order to support older rustc. The list under that comment is crossbeam-deque, crossbeam-utils, either, libc, rand, scoped-tls, and wasm_sync, and the comment says only some of them may lag. The consequence is that a transitive dependency cannot be assumed current just because its own project has moved on.

rayon-core carries its own version number, and the workspace holds only two libraries plus a demo

The repository is smaller than its reputation suggests. The top level holds src/, rayon-core/, rayon-demo/, tests/, ci/, FAQ.md, RELEASES.md, Cargo.toml, and the two license files. Cargo.toml declares a workspace with rayon-demo and rayon-core as members and ci excluded, and the package version there is 1.12.0. The dependency entry for rayon-core carries version 1.13.0 with a path pointing at the local copy, and a comment above it says these are both public dependencies, which is how rayon-core and either are marked. What that cannot do is give you a single number to reason about. Rayon and rayon-core version independently, so the pair in this tree is 1.12.0 alongside 1.13.0, and a lockfile that pins the pair tells you which core your iterator code was compiled against. either is pulled with default features turned off, which keeps the dependency surface small. The practical consequence is that reading a Rayon issue or a build failure often means looking at two crates rather than one, and the core crate is where the scheduling lives.

There are no GitHub releases here, so the version lives in Cargo.toml and the history in RELEASES.md

Distribution runs through crates.io, with API documentation on docs.rs, and this repository has no GitHub releases to browse. That detail changes how you obtain a specific version: the number in Cargo.toml is the one that matters, currently 1.12.0, and the change history is the RELEASES.md file in the tree rather than a release page with attached artifacts. The last push landed on 2026-10-27, so the project is being worked on even though nothing appears in a releases feed. Licensing is the dual MIT and Apache 2.0 arrangement, with LICENSE-APACHE and LICENSE-MIT in the root, and opening a pull request is taken as agreement with those terms, which is also what the contribution section means when it says code in PRs is assumed to be under the same dual licensing. What the release story cannot do is give you a signed or dated artifact to pin a deployment to, so a build that needs reproducibility has to pin the crate version and record it. The same caution applies to the FAQ, which lives in the repository at FAQ.md rather than on a separate site.

The demo answers with two keys instead of numbers, so no speedup figure comes with it

The repository ships a rayon-demo directory with several demonstrations, and the one named in the README is an N-body simulation with a visualization:

text
> cd rayon-demo
> cargo run --release -- nbody visualize

While it runs, pressing s executes sequentially and p executes in parallel, which is how you see the effect of the library yourself. The other demos are listed through the help output:

text
> cd rayon-demo
> cargo run --release -- --help

What this cannot do is report a number. The demo is a side-by-side visual comparison you drive from the keyboard, and no timings, speedup ratios, or hardware notes accompany it in the project documentation. The consequence is that the demo settles whether Rayon changes the behavior of your workload and settles nothing about how much faster it is on your machine. Any claim about a multiplier has to come from your own measurement, run in release mode, on the data you actually process, with the sequential version kept as the baseline. The same caution applies to the rest of the project, since the documentation describes the guarantees and the API but publishes no benchmark figures of its own.

Editorial conclusion

Use Rayon when the work divides along a collection you already own and the results can be recombined, since the iterator path handles scheduling for you. Look elsewhere when the order of side effects matters, when you are targeting the browser and have not budgeted for a threading adapter, or when your toolchain sits below rustc 1.85.0. Before adopting it, check the parallel method you rely on against the standard one, and decide early whether you will run on the default global pool or a custom ThreadPool.

Frequently asked questions

how to use rayon rust

Add the dependency, import the prelude in each module, and change your iterator call from foo.iter() to foo.par_iter(). Rayon then divides the data into tasks itself and adapts the split as it runs.

how to install rayon

Rayon is available on crates.io, so add rayon = "1.12" under [dependencies] in your Cargo.toml. It currently requires rustc 1.85.0 or greater, and the workspace is built on edition 2024.

Is rayon basically plastic?

That question is about the textile, and this repository is not about textiles. The project is a Rust library for data parallelism, published on crates.io as rayon with its API documentation on docs.rs.

Is rayon 100% cotton?

Nothing here discusses fabric content. The package describes itself with the keywords parallel, thread, concurrency, join, and performance, and it files itself under the concurrency category, which is a different Rayon entirely.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. rayon-rs/rayon on GitHub
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/rayon-rs-rayon.svg)](https://hysenlabs.com/projects/rayon-rs-rayon)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/rayon-rs-rayon.svg)](https://hysenlabs.com/projects/rayon-rs-rayon)

Was this useful?