turn-rs is a TURN server that deliberately does less
A pure rust implemented turn server.
At a glance
- What is it?
- turn-rs is a pure Rust implementation of a TURN server for WebRTC NAT traversal, built around long-term credentials, virtual ports only, a gRPC control API and a small set of cargo features. The README states high single-thread forwarding numbers and is equally clear that it is not trying to match coturn feature for feature, which is exactly the trade to weigh before adopting it.
- Who is it for?
- turn-rs fits a team that runs WebRTC media, wants a forwarding server with a small operational surface and a control API, and is willing to live with long-term credentials only and no public authentication schemes. It does not fit a deployment that needs the full authentication and configuration surface of a general purpose TURN server, and it does not fit a team that treats the project's own benchmark figures as a capacity plan.
- Can I use it commercially?
- Yes. MIT 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 39 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 October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A forwarding server for WebRTC media
turn-rs is described as a TURN server implemented in Rust, and the README explains what that means in one line: the TURN server is a VoIP media traffic NAT traversal server and gateway. The repository topics give the same picture from the other side, with stun, turn, webrtc and p2p.
So the job is narrow and important. When two browsers or two mobile clients want to exchange media across NATs, one of them usually cannot simply open a connection to the other. A TURN server relays the media, and in a WebRTC deployment that relay is often the most expensive part of the system, which is why the project spends its effort where it does.
The design goals are stated plainly: the project prioritizes core functionality, requires minimal configuration for use, and offers near-out-of-the-box usability. That is a deliberate narrowing, and the README is unembarrassed about it, saying that if you only need a pure TURN server to cope with WebRTC business and require excellent forwarding performance, the current project will satisfy you.
The audience is therefore the operator of a WebRTC service, the person who has to run a relay in front of a set of clients and wants a binary that starts, reads a configuration file and stays out of the way. It is not a general purpose SIP or telephony stack, and it is not trying to be.
The performance numbers come with a stated scope
The README makes performance claims, and they are specific enough to be checked against your own situation rather than simply admired.
The stated figures are 40 million channel data forwarding messages and 600,000 allocation requests per second within a single thread, excluding network stack overhead, with forwarding latency remaining below 35 microseconds, which the README compares to a complete local network send and receive delay between two points. The project attributes the speed to Rust's memory and concurrency safety, and adds that it uses pre-allocated memory in many places to cope with bursty performance.
The scope of those numbers is the part to read carefully. They are per thread, they exclude the network stack, and they are the project's own figures rather than an independent measurement. The README also says the project performs very high speed forwarding on the author's Raspberry Pi 4 and still performs well with a large number of clients, which is the more useful half of the claim for a person deciding whether this runs on small hardware.
The right way to use this is as an indication of the design intent, not as a capacity plan. A TURN server in production is usually limited by bandwidth and by the number of concurrent media streams, not by the forwarding path. What the figures do tell you is that the server is not going to be the bottleneck, which is the point of writing it in Rust at all.
Long-term credentials and virtual ports, by design
The feature list is short, and every item is a decision rather than a checkbox.
Only long-term credential mechanisms are used. Static authentication lists can be used in configuration files. And only virtual ports are always allocated, with no real system ports occupied. The last one is a design choice with an operational consequence: the server does not need to bind privileged or reserved ports on the host, so it can run as an unprivileged user and two instances can coexist on one machine without arguing over port numbers.
The transport layer supports both TCP and UDP, and supports binding multiple network cards or interfaces. Dual transport matters for WebRTC in practice, since UDP is what the media path wants and TCP is what the fallback path and some enterprise networks force you to use. Binding multiple interfaces is what lets one server serve several networks.
Then there is the gRPC API. The README describes it as a way for the TURN server to proactively notify an external service of events, and for the external service to proactively control the TURN server and manage the session. That is a meaningfully different shape from the usual TURN deployment, where the server is a dumb relay configured once and left alone. Here the server is something your control plane can drive, which is what makes it interesting as part of a larger WebRTC platform rather than a standalone relay.
The RFC list shows the protocol coverage
The standards the project implements are listed explicitly, and reading them tells you what kind of TURN server this is.
The list starts with RFC 3489, the classic STUN specification, and RFC 5389, the base new STUN spec. RFC 5769 is listed as test vectors for STUN protocol testing, which tells you the project takes protocol conformance seriously enough to run the published vectors. RFC 5766 is the base TURN specification, RFC 6062 is the TCP relaying TURN extension, and RFC 6156 is the IPv6 extension for TURN. The final entry is the TURN REST API, which is still a draft, and it is the mechanism by which a server hands out short-lived credentials to a client that authenticates elsewhere.
The presence of the REST API draft alongside the long-term credential policy is a coherent combination: an external service signs a short-lived credential and the TURN server validates it, which is the standard way to run TURN without handing your main account credentials to every client. What the feature list does not include is the older and more complicated short-term credential and long-term password mechanisms, and the README says only long-term mechanisms are used.
IPv6 and TCP relaying are both covered, which is more than many minimal implementations bother with, and the repository also carries a benches directory with a criterion benchmark named stun, plus property based tests through proptest in the development dependencies. Protocol testing is visible in the project rather than assumed.
Running it: a config file, a container image, a service script
There are three documented ways to get it running, and they are short enough to reproduce exactly.
The first is to take the compiled binaries from the GitHub release and start the server with a configuration file.
turn-server --config=/etc/turn-server/config.tomlThe configuration is TOML, and the repository ships an example file named turn-server.toml with the details of every option. The Cargo manifest shows toml as a dependency and the project description in the README calls out minimal configuration as a goal, so the example file is where you should look first rather than hunting for a separate manual.
The second is a container image published to GitHub Container Registry.
docker pull ghcr.io/mycrl/turn-serverThe README notes that a custom configuration file overrides the /etc/turn-server/config.toml path inside the image through -v, which is the usual mount, and the Dockerfile in the repository confirms it: the image copies the binary to /usr/local/bin/turn-server, copies the example turn-server.toml to /etc/turn-server/config.toml, and runs the server with that path as its command.
The third is a helper script for Linux services, which compiles the project and installs and starts the service.
./install-service.shThe repository also contains a turn-server.service unit, so the installation script has something to install, and the tree includes docs/, a website/ directory and an AGENTS.md that the README points to for detailed information instead of documenting the details here.
Cargo features decide the binary you ship
The build is a Cargo workspace, and the manifest is where the design decisions become concrete.
default = ["udp", "tcp", "ssl", "api", "prometheus"]
tcp = []
udp = []
ssl = ["dep:tokio-rustls", "tonic/tls-aws-lc", "dep:axum-server"]All features are enabled by default, and the README says that if you do not need a particular one you can reduce the package size by enabling only what you require. The five toggles are the UDP transport layer, the TCP transport layer, TLS encryption support, the gRPC API server and Prometheus support.
The dependency list explains the shape of the implementation. Tokio with the full feature set is the async runtime, axum and axum-server with the rustls feature are the HTTP stack used for the API and for TLS, tonic provides the gRPC server, mimalloc is the allocator, ahash and parking_lot handle hashing and locking, crossbeam-queue and clap and fern and toml and serde cover queues, argument parsing, logging and configuration. The crate targets edition 2024 and its version in the manifest is 4.1.6.
One asymmetry is worth knowing before you plan a deployment. The README has a note about the data plane: enabling server.interfaces.ssl on a TCP interface turns it into TLS, while the UDP transport does not support ssl. In other words, the TLS flag applies to the TCP side of the server, and the UDP path, which is the one WebRTC media actually uses, is plain. That is normal for TURN, where confidentiality comes from the media layer's own encryption, but it is the kind of detail that surprises people who expect a single TLS switch.
How it compares with coturn, and where it is the wrong choice
The README has a section comparing itself with coturn, and it is worth reading in full because it is unusually fair.
The author says they remain in awe and respect for coturn, which is a much more mature implementation with very comprehensive support for a wide range of features. The claim is that turn-rs is not a simple duplicate, and not a blind rewrite in someone else's image. The reasoning is that TURN is currently the largest use case in the WebRTC scene, that many features are not necessary for that business, and that keeping it simple and fast is the better choice.
That framing defines the limitation as precisely as a limitation can be defined. If your deployment needs the long tail of TURN features, the authentication schemes turn-rs does not implement, the exotic relay configurations or a decade of accumulated edge cases, coturn is the mature answer and turn-rs is not competing for that job. If your deployment is a straightforward WebRTC relay, the smaller surface is the feature.
The alternative approach, then, is a real fork in the road rather than a preference. coturn and turn-rs differ in what they optimise for: one is comprehensive and configuration heavy, the other is narrow and configuration light, and the deciding question is whether your requirements are typical or unusual.
There is a second caveat about the evidence. The headline numbers are the author's own, on the author's own hardware, excluding the network stack, and the README mentions a Raspberry Pi 4 in passing. Before sizing a deployment, measure the forwarding path with your own client count, your own media bitrate and your own network, because a relay's cost is dominated by bandwidth and concurrency long before it is dominated by the server's own processing. A fast server on a slow link is still a slow relay.
Editorial conclusion
turn-rs fits a team that runs WebRTC media, wants a forwarding server with a small operational surface and a control API, and is willing to live with long-term credentials only and no public authentication schemes. It does not fit a deployment that needs the full authentication and configuration surface of a general purpose TURN server, and it does not fit a team that treats the project's own benchmark figures as a capacity plan. Before you deploy it, read the example turn-server.toml and confirm your credential and port requirements against the feature list, and start from v4.1.6, released on 2026-09-14, with the last push on the same day. The licence is MIT.
Frequently asked questions
What is turn-rs and what is it used for?
It is a pure Rust implementation of a TURN server, which the README describes as a VoIP media traffic NAT traversal server and gateway. The project targets WebRTC deployments, prioritising core functionality, minimal configuration and forwarding performance.
How do I run the turn-rs server?
Take the compiled binary from the GitHub release and start it with a configuration file, using turn-server --config=/etc/turn-server/config.toml. There is also a container image at ghcr.io/mycrl/turn-server, and a helper script, install-service.sh, that compiles the project and installs and starts the Linux service.
Which authentication mechanisms does turn-rs support?
The feature list says only long-term credential mechanisms are used, and static authentication lists can be configured in the configuration files. The protocol list includes the TURN REST API draft, which lets an external service hand out short-lived credentials.
How does turn-rs differ from coturn?
The README states that coturn is a much more mature implementation with comprehensive feature support, and that turn-rs is not a duplicate of it. The difference in approach is that turn-rs keeps only what a typical WebRTC deployment needs, in exchange for minimal configuration and high forwarding performance.
Can I reduce the size of the turn-rs binary?
Yes. The README says all features are enabled by default, and that you can enable only the features you require. The cargo features are udp, tcp, ssl, api and prometheus, and the build is a release build with cargo build --release.
Official sources
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.
[](https://hysenlabs.com/projects/mycrl-turn-rs)Was this useful?