top of page

Zephyr vs FreeRTOS vs Eclipse ThreadX in 2026: A Decision Framework for Industrial IoT Firmware

Writer: Srihari Maddula
Srihari Maddula
Oct 20
16 min read

Updated: Oct 22

Shallow-focus photograph of source code on a screen
Photo: Shahadat Rahman / Unsplash

On 15 October 2026, Zephyr 4.3 reached its published end of life. Somewhere, a fleet of devices built and frozen against that release in late 2025 stopped receiving upstream fixes five days before this post was written, and the team that owns the fleet either planned for the date or is learning about it now. Nothing about the kernel changed that day. What changed is that a choice made in a design review, "which RTOS and which release," turned into a support obligation with a calendar attached.

That is the framing this post argues for. Most RTOS comparisons rank scheduler latency, memory footprint, and feature lists. Those matter, and they are rarely what decides whether a product line is still maintainable four years later. The decision framework below ranks the factors that are hard to change after the first release, puts them first, and treats the benchmark numbers as tie-breakers.

The rule: choose the RTOS by the constraint you cannot change later, which is usually the support lifecycle and the silicon vendor's software, not the kernel. Kernels are interchangeable in a way that update streams, driver ecosystems, and team skills are not.

Compare RTOS candidates on what you will be forced to live with in year four: security updates, release cadence, vendor drivers, and who on your team can debug it at midnight. Compare kernels last.

First, the Question Nobody Asks: Do You Need One?

An RTOS earns its place when a device must do several things with different timing needs at once: service a radio stack, sample sensors on a schedule, handle a bootloader and update path, run a command interface. A scheduler, queues, and mutexes let those activities coexist without hand-rolled timing logic.

Some devices do not need one. A battery node that wakes, reads a sensor, transmits, and sleeps can be a state machine in a loop, driven by a timer interrupt. It has fewer moving parts, a smaller attack surface, simpler timing analysis, and nothing to update except your own code. The honest test is whether concurrency is real or imagined. If your design has one activity at a time and the rest is waiting, a superloop is the more reliable answer, and the RTOS question disappears.

The usual drift that pushes teams into an RTOS is the vendor SDK: the radio or connectivity stack arrives built around one, and adopting the stack means adopting the kernel. That is a legitimate reason, and it deserves to be recognised as the real decision, not hidden behind a feature comparison.


The Candidates in One Table

Three open-source options cover most industrial IoT microcontroller work in 2026, alongside embedded Linux for more capable processors.

Property

Zephyr

FreeRTOS

Eclipse ThreadX

Governance

Linux Foundation project, many vendor members

Amazon-maintained, open source

Eclipse Foundation (formerly Azure RTOS, ThreadX before that)

Licence

Apache-2.0

MIT

Open source under Eclipse stewardship (confirm the licence of the release you use)

Shape

Full platform: kernel, drivers, networking, Bluetooth, filesystems, build system, device tree

Kernel plus libraries; middleware and drivers come from you or the silicon vendor

Compact kernel with companion components for file system, networking, USB, and GUI

Release model

Six-month cadence (April and October targets), LTS line with multi-year security backports

Long-term-support releases with a published support window

Open-source releases under Eclipse, check the current release page for cadence

Build and configuration

CMake, west, Kconfig, devicetree: steep learning curve

Whatever the SDK or your project uses

Whatever the SDK or your project uses

Host-side testing

Native simulation target and the Twister test runner

POSIX simulator port available

Simulation options vary

A 2024 survey from the Eclipse Foundation, as reported by secondary sources, put embedded Linux first among surveyed developers at 46 percent, with FreeRTOS at 29 percent, Zephyr at 21 percent, and ThreadX at 13 percent, with Zephyr showing the strongest growth that year. Survey numbers describe popularity, which correlates with hiring and community help, but they do not say which fits your product.


Criterion One: The Support Lifecycle You Are Signing

This criterion has become sharper in 2026, for two reasons. The EU Cyber Resilience Act requires manufacturers to provide security updates through a support period of at least five years in most cases, with its main obligations applying from December 2027, and reporting duties already live since September 2026 (see our post on the CRA for firmware teams). And RTOS release cadences are fast enough that a fleet frozen on a release can fall out of upstream support while still in warranty.

Zephyr's schedule illustrates the pattern. Release 4.3 shipped in November 2025 and its published end of life was 15 October 2026. Release 4.4 shipped on 14 April 2026, with an end-of-life date reported for April 2027. A six-month cadence with an eleven-to-twelve-month support window for ordinary releases means a product built on a non-LTS release must upgrade roughly annually or accept the fork. Zephyr's long-term-support line is the answer for products with long lives: it carries security backports for multiple years under project policy. Confirm which release is the current LTS and how long its backports run before you pin to it, because the answer changes as the project evolves, and published comparisons disagree on details.

FreeRTOS publishes long-term-support releases with a stated two-year support window and an extended maintenance option, and its slower, kernel-centred cadence suits products that want to change little. ThreadX under Eclipse offers a stable, compact codebase with a history of industrial use. For each, ask the same four questions:

  • How long will upstream backport security fixes for the version I ship?

  • Who triages and publishes vulnerabilities, and how quickly?

  • How do I learn about a vulnerability in time to meet a 24-hour reporting clock?

  • What is my cost, in engineering weeks per year, to track and merge updates?

The support period you promise customers should come out of those answers, not out of a marketing sentence. A five-year promise on a kernel with a two-year upstream window means you will carry three years of patches yourself, and that is a staffing decision to make on day one.

A product on a non-LTS RTOS release is a product with an upgrade project scheduled for twelve months after launch, whether or not anyone has put it on the roadmap.
The strongest reason to choose a kernel is that your silicon vendor's engineers support it.

Criterion Two: The Gravity of the Silicon Vendor's SDK

Most industrial teams choose a microcontroller first, and the vendor's software shapes the rest. Some vendors ship their SDK around FreeRTOS, with drivers, radio stacks, and examples assuming it. Others support Zephyr through vendor-backed ports of varying maturity, and some of the most capable radios now ship with first-class Zephyr support. A few support several kernels with different levels of completeness.

Three practical checks prevent surprises:

  1. Support level of your exact part. Zephyr's board support ranges from mature, vendor-maintained to community-maintained. Find your board's page and see who maintains it and how recently it changed.

  2. Driver completeness. Check that the peripherals you need (low-power timers, DMA-driven UART, flash with a bootloader-compatible layout, your radio) have drivers in the kernel's native model, not just in a vendor example.

  3. Low-power behaviour. An RTOS tick can keep a processor awake. Confirm that tickless idle is supported on your silicon, and measure sleep current with the RTOS running, since a kernel that wakes every millisecond defeats a microamp budget.

When the vendor SDK is built on one kernel, fighting it carries a continuous cost in merge conflicts and unsupported combinations.


Criterion Three: Footprint, Measured, Not Quoted

Memory footprint arguments generate more heat than light. Published comparisons disagree. One 2026 comparison reports the kernel footprint of Zephyr at roughly twice that of FreeRTOS, but a system-level gap of only tens of percent once networking, cryptography, and update support are included, and another puts the system-level difference at 15 to 25 KB of flash and 4 to 6 KB of RAM. Both can be true for different configurations. What matters is that kernel numbers say little about a product that also carries a TLS library, a protocol stack, and a bootloader.

On a part with ample memory, the gap does not matter. On a part at the edge of its RAM (a 64 KB device is the common threshold in discussions), the smaller footprint wins, and the difference is real. Measure your own build rather than trusting a table.

For Zephyr, the build system produces memory reports:

# Zephyr: build and inspect where flash and RAM go
west build -b <board> app/ -- -DCONFIG_SIZE_OPTIMIZATIONS=y
west build -t rom_report > rom.txt       # flash usage by symbol and subsystem
west build -t ram_report > ram.txt       # RAM usage by symbol and subsystem

# Typical prj.conf trimming for a small node
CONFIG_LOG=n
CONFIG_SHELL=n
CONFIG_ASSERT=n
CONFIG_PRINTK=n
CONFIG_MAIN_STACK_SIZE=1024
CONFIG_BT=n
CONFIG_NET_BUF_POOL_USAGE=n

For FreeRTOS, the footprint depends on the configuration header and the ports you pick, and stack sizing is the usual trap:

/* FreeRTOSConfig.h -- settings that most affect footprint and diagnosability */
#define configTOTAL_HEAP_SIZE            ( 24 * 1024 )
#define configMINIMAL_STACK_SIZE         ( 128 )          /* in words */
#define configUSE_TIMERS                 1
#define configUSE_MUTEXES                1
#define configUSE_TICKLESS_IDLE          1
#define configCHECK_FOR_STACK_OVERFLOW   2
#define configUSE_TRACE_FACILITY         1

/* Find out how much stack each task really uses -- run this in a long soak test */
UBaseType_t headroom = uxTaskGetStackHighWaterMark( NULL );   /* words never used */

Measure on the target at the end of a long soak with all features active. Stack high-water marks from a ten-minute demo are not a sizing basis.

Criterion Four: The Stacks You Will Not Write Yourself

An industrial IoT product needs a connectivity stack, a security library, a bootloader and update mechanism, and a way to persist configuration. Writing any of them from scratch is a mistake, and the question is which kernel makes the proven ones easiest to adopt.

Need

Zephyr

FreeRTOS

Notes

MQTT and cloud connectivity

Native MQTT client in the networking stack

coreMQTT and related libraries from the vendor ecosystem

Both workable; check TLS integration

TLS and cryptography

Mbed TLS integration and the PSA crypto API

Mbed TLS, often via vendor SDK

Pin versions and track advisories

Bluetooth LE

Native Bluetooth host and controller options

Vendor-provided stacks

Zephyr's native stack is a major draw for BLE products

LoRaWAN

Subsystem integrating a LoRaMac implementation

Vendor or third-party stacks

Verify the supported regional plans and class modes

Bootloader and update

MCUboot, integrated with the build and signing flow

MCUboot or vendor bootloaders

MCUboot is not tied to a kernel

File system and persistence

LittleFS, FAT, and settings subsystem

Vendor or third-party

Wear levelling matters for logged data

Notice the last pattern: the best components are mostly kernel-independent. MCUboot, Mbed TLS, and LittleFS run on several kernels. The kernel decides how much integration work remains, not whether the capability exists.


Criterion Five: Can You Test Without Hardware?

A firmware team's iteration speed depends on how much it can verify without a board in hand. Zephyr's native simulation target compiles an application as a Linux executable, and its Twister runner executes tests across boards and configurations in CI:

# Run unit and integration tests on the host, no hardware needed
west twister -p native_sim -T tests/ --inline-logs

# Run the same tests on real hardware attached to the CI runner
west twister -p <board> --device-testing --device-serial /dev/ttyACM0 -T tests/

FreeRTOS offers a POSIX simulator port that serves the same purpose with less out-of-the-box tooling around it, so teams typically wrap their own harness. Whichever kernel you choose, structure the application so that logic sits behind clean interfaces and hardware access is thin, which makes host-side testing possible on any of them.

Testability links directly back to the support lifecycle. A team that can run its full regression suite in CI in ten minutes can afford to merge upstream security releases every quarter. A team that must test by hand on a bench will defer merges until they pile up.

Mutexes for exclusion, semaphores for signalling. A binary semaphore does not inherit priority.

Criterion Six: Determinism, and the Mutex Trap

All three kernels provide priority-based preemptive scheduling, and the timing differences between them are rarely what limits a product. What limits it is a design error that every RTOS lets you make: priority inversion. A low-priority task holds a lock that a high-priority task needs, and a medium-priority task preempts the low one, so the high-priority task stalls for an unbounded time. The remedy is a mutex with priority inheritance, and the common mistake is using a binary semaphore for mutual exclusion instead.

/* FreeRTOS: use a MUTEX (priority inheritance), not a binary semaphore, to guard a resource */
SemaphoreHandle_t bus_lock = xSemaphoreCreateMutex();          /* inherits priority */
/* NOT: xSemaphoreCreateBinary();  binary semaphores do not inherit priority */

if (xSemaphoreTake(bus_lock, pdMS_TO_TICKS(50)) == pdTRUE) {
    spi_transfer(...);
    xSemaphoreGive(bus_lock);
}
/* Zephyr: k_mutex implements priority inheritance */
K_MUTEX_DEFINE(bus_lock);

if (k_mutex_lock(&bus_lock, K_MSEC(50)) == 0) {
    spi_transfer(...);
    k_mutex_unlock(&bus_lock);
}

Whichever kernel you pick, put "mutexes for exclusion, semaphores for signalling" in the coding standard and check for it in review. This one rule prevents more intermittent field failures than any scheduler comparison.


Criterion Seven: Certification and Safety Evidence

Products in functional-safety domains (machinery, medical, rail, automotive) need evidence beyond good practice. The RTOS landscape here is more commercial. ThreadX has a history of safety certifications under its previous owners, and you must check whether a certificate covers the specific open-source release you intend to ship, since certificates attach to defined versions and processes. FreeRTOS has a commercially licensed safety-certified derivative from a third party. Zephyr has an active safety effort aiming at certifiable processes, and teams with a hard certification requirement should check its current status with the project and with a certification body before building on it.

If your product sits in a certified domain, this criterion trumps every other in this post, because the certification route fixes the kernel. If it does not, resist the temptation to let a safety brochure influence a choice that is really about maintainability.


What About Rust?

Rust deserves a mention because teams ask. Embedded Rust is production-viable in 2026 for many common microcontroller families, with async frameworks that run without an RTOS and with real memory-safety advantages for protocol parsing and update code. A mid-2026 survey of the field describes coverage as good for common parts and thinner than C for the long tail, with a notable gap in wireless stacks: for radio-heavy connected products, a hybrid of Rust application code on a C-based stack, or plain Zephyr, still beats pure Rust on time to market. The ecosystem's dependencies also move fast, so pin versions and budget for migration work, in a way that Zephyr's LTS releases largely spare you.

A reasonable use of Rust today is in the places where memory safety pays most: parsers for untrusted network input, the update and verification path, and cryptographic glue, called from a C-based platform.


Turning the Criteria Into a Decision

Weights express what your product cannot compromise. A short script makes the weighting explicit and forces the team to argue about numbers in the open instead of over opinions in a meeting:

# rtos_score.py -- weighted decision matrix; scores 1 (poor) to 5 (strong) per criterion
weights = {
    "support_lifecycle":   0.22,   # LTS length, security backports, CRA fit
    "vendor_sdk_fit":      0.20,   # your silicon's maintained support
    "stacks_available":    0.15,   # connectivity, security, bootloader
    "footprint_fit":       0.10,   # against your RAM/flash headroom
    "testability_ci":      0.10,   # host-side tests, CI speed
    "team_skills":         0.13,   # who can debug it at midnight
    "safety_evidence":     0.05,   # raise to 0.30 if certification is required
    "determinism":         0.05,
}
assert abs(sum(weights.values()) - 1.0) < 1e-9

candidates = {
    "Zephyr (LTS)":   dict(support_lifecycle=4, vendor_sdk_fit=3, stacks_available=5, footprint_fit=3,
                           testability_ci=5, team_skills=2, safety_evidence=3, determinism=4),
    "FreeRTOS + SDK": dict(support_lifecycle=4, vendor_sdk_fit=5, stacks_available=3, footprint_fit=5,
                           testability_ci=3, team_skills=5, safety_evidence=3, determinism=4),
    "Eclipse ThreadX": dict(support_lifecycle=3, vendor_sdk_fit=3, stacks_available=3, footprint_fit=5,
                            testability_ci=2, team_skills=3, safety_evidence=4, determinism=5),
}
for name, sc in candidates.items():
    total = sum(weights[k] * sc[k] for k in weights)
    print(f"{name:18s} {total:.2f}")

The scores above are placeholders to show the method, not a verdict on the kernels, because every number depends on your silicon, your team, and your product. The value of the exercise is the argument it provokes. When two people disagree about a score, they are disagreeing about a fact (does the vendor maintain this driver?) that can be checked, which is a better use of an afternoon than debating adjectives.


Measuring Latency and Jitter on Your Own Board

Scheduler benchmarks from vendors measure idealised cases. What matters for your product is the latency from an interrupt to the task that handles it, on your silicon, with your other interrupts and your flash wait states. On Cortex-M parts, the cycle counter in the debug watchpoint unit gives cycle-accurate timing for almost no cost:

/* Cortex-M: measure interrupt-to-task latency with the DWT cycle counter */
#include "core_cm4.h"     /* or your device header */

static volatile uint32_t t_isr;
static volatile uint32_t worst_cycles;

void dwt_init(void) {
    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
    DWT->CYCCNT = 0;
    DWT->CTRL  |= DWT_CTRL_CYCCNTENA_Msk;
}

void sensor_irq_handler(void) {
    t_isr = DWT->CYCCNT;                 /* timestamp at ISR entry */
    signal_task_from_isr();              /* semaphore give / k_sem_give / task notify */
}

void sensor_task(void *arg) {
    for (;;) {
        wait_for_signal();               /* blocks until the ISR signals */
        uint32_t lat = DWT->CYCCNT - t_isr;
        if (lat > worst_cycles) worst_cycles = lat;   /* log percentiles in a soak test */
        process_sample();
    }
}

Run this over hours with the radio and storage active, and record the worst case, not the average. Divide cycles by the core clock to get microseconds. If the worst case fits comfortably inside your timing requirement, the kernel's scheduler is not your problem, and the question closes. If it does not, the usual causes are long interrupt-disabled sections in drivers, flash cache misses during a write, or a priority arrangement that lets a long task block a short one, and none of those is fixed by changing kernels.

Every local kernel patch becomes a merge conflict at every upgrade.

What an Upgrade Actually Costs

The lifecycle argument deserves numbers from your own history. Track, for every upstream release you merge, the engineering time from branch to regression-clean. After two or three cycles you know your cadence cost, and you can budget it. A rough planning pattern for a small team looks like this:

Activity

Typical effort per merge

Notes

Read release notes and advisories, list affected components

Half a day

Faster with an SBOM that names components

Rebase or merge, fix build breaks

One to three days

Grows with local patches to the kernel

Regression test in CI and on target hardware

One to two days

Shrinks with automated host-side tests

Soak test on a small field or lab fleet

One to two weeks elapsed, little effort

Run in the background

Release, sign, stage the rollout

One to two days

Depends on the update pipeline

The multiplier is the number of local patches you carry. Each modification to the kernel or a vendor driver that is not upstreamed becomes a merge conflict at every upgrade. A strict policy keeps this small: patch upstream where you can, wrap rather than modify where you cannot, and keep a list of every local change with the reason it exists. A fleet carrying forty local kernel patches has chosen a quiet fork, and its true support cost is higher than the project's published policy suggests.


Hardening Features Worth Switching On

Whichever kernel you ship, the security work belongs in the platform configuration as much as the application. Features common to modern microcontroller RTOS builds, and what each buys:

Feature

What it protects against

Where it shows up

Memory protection unit (MPU) isolation of tasks

A bug in one task corrupting another, or a compromised parser overwriting the stack

Zephyr user-mode threads and memory domains; FreeRTOS MPU ports

Stack overflow checks and canaries

Silent stack corruption that becomes an exploit or a heisenbug

Kernel configuration options in all three

Secure boot with signed images and rollback protection

Running modified firmware

MCUboot or vendor bootloaders

Read-out protection and debug-port locking

Key and firmware extraction from a fielded unit

Silicon option bytes, set in manufacturing

Hardware crypto and secure key storage

Software keys sitting in readable flash

Vendor crypto engines through the PSA crypto API

Disabled unused interfaces and services

Attack surface (shell, debug UART, unused protocols)

Kconfig options, configuration headers

Treat the configuration as a security artefact: review it, version it, and record in the release bundle which options were enabled. This is the evidence an auditor or customer will ask for when the Cyber Resilience Act's secure-by-default requirements apply to your product, and it costs nothing to collect if you collect it every release.


Two Product Lines, Two Different Answers

Two composite cases, genericised, show how the same framework produces different decisions.

Case A: a LoRaWAN sensor family with a five-year support promise. A team of eight engineers plans a family of battery-powered industrial sensors for export, including to the EU, with a five-year security-update commitment. The silicon vendor supports both FreeRTOS and Zephyr, with the Zephyr port maintained by the vendor. The team scores support lifecycle and stacks highest in their weighting, because the CRA makes a defined update stream a product requirement, and they need a LoRaWAN subsystem and a signed-update bootloader. Zephyr's LTS line, MCUboot integration, and native host-side tests win on those criteria. The cost is real: the devicetree and Kconfig learning curve took the team about two months to climb, and two engineers needed dedicated training. They pinned to the LTS release, set a quarterly merge cadence for upstream security backports, and wrote the support-period budget into the product plan.

Case B: a cost-sensitive gateway add-on on a small, RAM-limited microcontroller. A different team ships a small protocol-converter module on a part with 64 KB of RAM, built on a vendor SDK that assumes FreeRTOS, with a three-year product life, domestic sales only, and an existing team of five engineers who know FreeRTOS well. Footprint, vendor fit, and team skills dominate the weighting, and FreeRTOS wins comfortably. The team still adds the disciplines that the lifecycle criterion teaches: they pin the LTS release, subscribe to its security advisories, and keep an SBOM per release so a future export decision does not require rework.

The frameworks agree and the products differ. Neither team spent time arguing about scheduler latency.


When You Should Not Switch

Existing products deserve a warning. A working fleet on an older kernel should usually stay on it until the next hardware platform. A migration changes timing, memory behaviour, and driver code all at once, and requalifies everything. The better move is to adopt the lifecycle disciplines (pinned versions, an SBOM, an advisory subscription, a tested update path) on the current kernel, and make the kernel choice at the next hardware spin, when drivers are being rewritten anyway.

Switching also fails when the reason is fashion. A team that moves to a new kernel because it is popular, with no concrete gain in support, stacks, or testability, pays a large cost for a small benefit. Write down what the migration buys and what it costs in engineering weeks before approving it.


A First Month of Work

  1. List your constraints: silicon, memory headroom, support period, certification needs, export markets, and team skills. Rank them.

  2. Check your vendor's actual support for each kernel on your exact part: who maintains it, when it last changed, which peripherals are covered.

  3. Read each candidate's support policy and write down the upstream support window, LTS commitments, and advisory process. Convert the result into engineering weeks per year.

  4. Build a thin vertical slice on your top two candidates: boot, a sensor read, a radio transmission, a signed update. Measure flash, RAM, sleep current, and wake latency on the real board.

  5. Run the weighted matrix with the team, and argue about the facts behind each score.

  6. Decide, then pin: one LTS or stable release, version-locked toolchain and dependencies, and a written upgrade cadence.

  7. Wire up the lifecycle: SBOM generation in CI, an advisory subscription for the kernel and the main libraries, a host-side test suite, and a rehearsed update path.

  8. Review annually, at the support-window boundary, not at the moment an advisory arrives.


Back to the Fifteenth of October


The date in the opening paragraph passed without drama for teams that had a calendar and a cadence, and with a scramble for teams that did not. Kernel debates are fun and mostly beside the point. The decision that defines your next five years is who patches the thing, how fast you can ship the patch, and whether the engineers who will do the work chose the platform they are now maintaining.


Related reading

EurthTech is an engineering-first product design and embedded systems company with a development center in Hyderabad. To discuss a project, write to connect@eurthtech.com or see https://www.eurthtech.com/case-studies.

Comments


EurthTech delivers AI-powered embedded systems, IoT product engineering, and smart infrastructure solutions to transform cities, enterprises, and industries with innovation and precision.

Factory:

Plot No: 41,
ALEAP Industrial Estate, Suramapalli,
Vijayawada,

India - 521212.

  • Linkedin
  • Twitter
  • Youtube
  • Facebook
  • Instagram

 

© 2025 by Eurth Techtronics Pvt Ltd.

 

Development Center:

4th Floor, Krishna towers, 100 Feet Rd, Madhapur, Hyderabad, Telangana 500081

Menu

|

Accesibility Statement

bottom of page