After months of development, I am so excited to announce the first release candidate of Ferron 3, a fast, debuggable web server.
Ferron 3 will help you while debug your web infrastructure, with less guesswork. Compared to current stable Ferron 2, Ferron 3 offers more comprehensive observability capabilities (like signal correlation, including OTLP metric exemplars).
Ferron 3 also brings improved performance in multiple areas (for example, static file serving) compared to Ferron 2.
The story of Ferron 3
It all began with ChatGPT mentioning possible future Ferron 3 (ah, we get it… 😅).
When I was exploring future possibilities to extend Ferron 2, I ended up getting a suggestion of a possible future major version of Ferron 3 that focuses a lot on observability.
So I explored and drafted the initial architecture for Ferron 3, hoping to get performance higher than Ferron 2 (same for low-level primitives I was building before Ferron 3).
Then as I hacked together an early “Titanium” prototype of it (yes, it was rough code) and Ferron 3 progressed, I found out an advantage of Ferron 3 that the original suggestion mentioned: very strong observability capabilities, which would help reduce operators’ guesswork while debugging.
So I put my focus into improved debuggability and observability of the web server. And after over 5 months, I am so excited that Ferron 3 is stabilizing and am now releasing a version close to stable Ferron 3.
Observability
What’s unique in Ferron 3 are the very strong observability capabilities.
There are other servers that have such observability capabilities, but they are either expensive (enterprise API gateways) or hard-to-setup (Envoy). Ferron 3 brings ease of debugging into a free, easy-to-configure web server that can be configured like this:
{
observability {
provider otlp
logs https://collector:4318/v1/logs
metrics https://collector:4318/v1/metrics
traces https://collector:4318/v1/traces
service_name "myferron"
}
}
example.com {
proxy http://examplesite:8080/
}Even without OpenTelemetry or any fancy observability backend, you can still use traditional log files. They ship by default with greppable anchors for correlating logs together, so you don’t have to guess what happened based on timestamps (this especially matters for long-lived connections like WebSockets).
Performance
Ferron 3 also shows significant performance improvements over Ferron 2, especially in static file serving.
From https://ferron.sh/blog/ferron-3-0-0-beta-11:
Results
Web server Requests/sec Avg latency Max latency Transfer/sec Socket errors NGINX 348,801.40 5.94 ms 116.49 ms 0.93 GB/s 0 Ferron 3 (dev / beta.11, epoll) 333,299.71 7.04 ms 128.78 ms 0.92 GB/s 0 Ferron 2 (epoll) 302,917.52 9.04 ms 233.13 ms 818.99 MB/s 0 Ferron 3 (beta.8, epoll) 293,941.50 8.67 ms 193.63 ms 831.72 MB/s 0 Caddy 124,584.30 97.21 ms 2,000.00 ms 343.61 MB/s 22 timeouts
You can also speed up your WordPress (or other PHP sites) when using Ferron 3 using an LSCache plugin (Ferron 3 has a cache that can be easily configured to be LSCache-compatible):
example.com {
proxy http://127.0.0.1:8080
cache {
litespeed_override_cache_control # <-- Enables LSCache semantics
}
}What’s changed from 3.0.0-beta.11
OK, I am going to list the changes, since this is still a testing version, but close to production.
Ferron 3.0.0-rc.1 brings some stability and bugfixes on top of Ferron 3.0.0-beta.1 as shown below
ACME automatic TLS fixes
When people reported Ferron’s website had TLS errors, we investigated why, and found that our CA (Actalis) has revoked ACME-obtained certificates on August 31, 2026, and informed us that revoked certificates would be renewed automatically if ACME client supports ARI. And then I found out that although I claimed that Ferron supported ARI, it didn’t work due to implementation bug. I have then fixed an issue where automatic renewal information was not applied correctly, leading to confusion about certificate expiration.
Also, I have improved ACME provider fallbacks by retrying when certificate provisioning fails (not just when the account creation fails).
One time, when I was reloading a web server using SIGHUP, I found that the TLS certificate isn’t installed for some time. Certificates are now reused from cache early before ACME provisioning cycles to mitigate TLS certificate errors after reloading the configuration.
HTTP server fixes
When I read a GitHub issue about SSE not working, I found out that HTTP/1.x and HTTP/2 servers buffer instead of streaming response bodies. I have now fixed response body streaming to avoid buffering instead of streaming, improving performance and memory usage. This also allows Ferron to be used as a reverse proxy for web applications that use SSE (Server-Sent Events).
Also, I fixed the listener backlog size to be 4096 on Linux (I thought -1 would work here, but it would be equivalent to 0 here).
Observability improvements
When I checked my Grafana dashboard, I noticed some metric exemplars linked to traced that don’t exist (they’re sampled out). Metric exemplars are no longer linked to traces that are sampled out (and thus not exported) to avoid misleading observability tools and reduce debugging friction.
Ferron 3 stable coming soon
Ferron 3 is approaching closer and closer to a stable, production-ready web server. I just opened a community discussion forum so you can discuss about various topics related to Ferron 3.
The release candidate phase would focus on stabilizing the web server, so you can use it for production, without any hidden surprises.
As always, I welcome feedback, bug reports, and testing results.
Full changelog
You can see the complete changelog for Ferron 3.0.0-rc.1 in the release notes.
Try it
- Documentation: https://ferron.sh/docs/v3
- GitHub repo: https://github.com/ferronweb/ferron/tree/develop-3.x
Install Ferron 3 using the installer:
sudo bash -c "$(curl -fsSL https://get.ferron.sh/v3)"