Most C++ projects don't fail on algorithms. They fail on threads, IPC and brittle integration code.
Areg takes that work off your hands. Describe a service interface once: the code generator writes the proxies, the serialization and the dispatch, the framework runs each component in the thread the model gives it and finds services by name, and you write the logic.
~9.9 Β΅s one-way latency (P50) and ~6.5 GB/s sustained throughput (8 GB/s peak) over TCP loopback, with full service dispatch, on a laptop Core i7 running Linux. Conditions and data
For C++ on devices, desktops and servers in trusted networks. Not for web services or public internet endpoints.
You write the logic. The generated base classes deliver each call to the component's thread:
// Provider thread or process: answer the request
void ServiceProvider::request_hello_service(const areg::String & client)
{
std::cout << "provider: hello, " << client << std::endl;
response_hello_service(true);
}
// Consumer thread or process: receive the answer, asynchronously
void ServiceConsumer::response_hello_service(bool success)
{
std::cout << "consumer: " << (success ? "greeted" : "failed") << std::endl;
}You decide where it runs. Here, two threads in one process:
areg::Model model("HelloModel");
model.add_thread("ProviderThread")
.add_component<ServiceProvider>("ServiceProvider")
.add_supported_service(HelloService::ServiceName, HelloService::InterfaceVersion);
model.add_thread("ConsumerThread")
.add_component<ServiceConsumer>("ServiceConsumer")
.add_dependency_service("ServiceProvider");For two processes the classes stay the same: the interface is marked Public, each
process loads its part of the model, and mtrouter connects them.
Full working code: one process Β·
two processes Β·
model in plain C++ Β· How it works
You can setup and start your own project, replace myapp with your real project name:
git clone https://github.com/aregtech/areg-sdk.git
sh areg-sdk/tools/setup-project.sh --name myapp --root myapp --mode local --sdk-root areg-sdk
cd myapp
cmake -B build
cmake --build build -jOn Windows without a POSIX shell, run areg-sdk\tools\setup-project.bat with the same options.
Run myapp from build/bin/ (the file name carries a platform suffix). It prints
provider: hello, ServiceConsumer and consumer: greeted, then exits.
Needs a C++17 compiler, CMake 3.20+ and Java 17+, which runs the code generator during the build.
If Areg saves you work, a β helps other C++ developers find it.
Note
π€ Coding with an AI agent? Areg ships a guide, generators and checkers so an agent
that has never seen the areg framework can still build on it correctly. Agentic coding
- Why Areg
- How it works
- Agentic coding
- Performance
- Embedded ready
- Areg vs. alternatives
- Getting started
- Architecture
- Network deployment
- Use cases
- Tools
- Project status
- Roadmap
- Documentation
- License
- Community
- Less infrastructure code: threading, IPC, service discovery and reconnection come from the framework and the generator instead of being rebuilt in every project. (Estimated time savings)
- No locks needed in component code: its calls run only in the thread that owns it; raw bytes route to that thread before any deserialization.
- No startup-order logic: services find each other by name, wherever they run, with no retry loops.
- Recovery built in: the watchdog restarts a stuck component thread; consumers are notified when a service disappears and reconnect when it returns.
- Test before hardware exists: register a simulation under the same service name and the rest of the system never notices. No conditional compilation, no mock frameworks.
Areg implements Object RPC (ORPC): components expose typed interfaces and communicate through generated proxies. Consumers refer to a service by name, not by address. The framework finds the provider in the same thread, another process or another machine, and delivers every call to the thread that owns the component.
The interface is a .siml document, designed in Lusan
or edited as XML. This is the request of the example above:
<Method ID="2" Name="hello_service" MethodType="Request" Response="hello_service">
<ParamList><Parameter ID="51" Name="client" DataType="String"/></ParamList>
</Method>One CMake line generates the serialization, proxies, events and the provider and consumer base classes, and links them:
addServiceInterface(MyServiceLib ./services/MyService.siml)| The framework handles | You write |
|---|---|
| thread lifecycle and message dispatch | the service interface |
| service discovery and registration | the logic in the provider and consumer classes |
| request, response and broadcast routing | the model: which component runs in which thread |
| watchdog, connection loss and reconnection |
The model can be written in plain C++, as above, or with the BEGIN_MODEL macros the
examples use. Details: Service interface guide Β·
Code generator.
Areg is built to be learned by coding agents while they work. The repository is the
course: AGENTS.md routes an agent to the one page its task needs. An
agent that has never seen Areg learns to write a service interface (.siml), a state
machine (.fsml) and a data type (.dtml), and wire them into a running project -- not
an API it half-remembers from training.
Try it: point your agent at one of eight ready prompts -- coffee machine, ATM, elevator, greenhouse -- and watch it design, generate and build a service from nothing; the same harness scores it against hidden checks and runs the identical task on gRPC to compare.
In our runs, agents finished the task on Areg as reliably as on gRPC: 57 of 57 runs passed every hidden probe over 3 days, on 4 tasks and 3 model families, and so did all 10 of the latest runs of both frameworks. With Claude Code and Sonnet 5.5, on the coffee machine, an agent on Areg wrote about 3x less C++ by hand than on gRPC (386-420 lines against 1,252-1,411), used 37% fewer output tokens and 34% less model time, with no filesystem searches, and cost a median of $0.71 against $0.80 -- within $0.03 from run to run, where gRPC runs varied by a third. Both needed about 9 API requests. With the earlier Sonnet 5 the gap was wider: Areg needed about half the API requests of gRPC (median 26 against 55.5). GitHub Copilot's GPT-5.6-Terra also passed 5 of 5 hidden probes, in as few as 12 API requests. Agent runs vary: 4 runs per framework, ranges and method.
Measured on mobile-class consumer hardware with the full stack active:
serialization, event dispatching and multithreading. These are not raw socket numbers.
Raw output and methodology are published for independent verification:
current latency dataset (bare TTY) Β·
earlier round (gnome-terminal).
| Platform | CPU | ~3 MB, GB/s | ~0.5 KB, msg/s |
|---|---|---|---|
| Linux Ubuntu ΒΉ | i7-13700H (DDR4) | ~6.5 sust. / ~8.0 peak | ~2.0M sust. / ~2.5M peak |
| macOS native Β² | M3 Pro (LPDDR5) | ~6.5 sust. / ~7.0 peak | ~2.5M sust. / ~3.0M peak |
| Windows 11 Β³ | i7-13700H (DDR4) | ~2.7 | ~2.5M+ |
ΒΉ Ubuntu 26.04, Performance power mode. Peak = best short run; sustained = 5+ min run.
Β² No network tuning.
Β³ Latest runs; sustained and peak are not reported separately.
Timestamps span the full call path, from before serialization at the sender to after
dispatch at the receiver. OWT = one-way (2 hops). RTT = round trip through mtrouter
(4 hops). Linux runs from a bare TTY with mtrouter, provider and consumer each pinned to
a core (methodology).
| Platform | CPU | OWT Min | OWT P50 | RTT Min | RTT P50 |
|---|---|---|---|---|---|
| Linux Ubuntu | i7-13700H (DDR4) | 9.6 Β΅s | ~9.9 Β΅s | 19.1 Β΅s | ~19.5 Β΅s |
| macOS M3 Pro | Apple M3 (LPDDR5) | 21.6 Β΅s | 31.4 Β΅s | 46.0 Β΅s | 62.5 Β΅s |
| Windows 11 | i7-13700H (DDR4) | 32.5 Β΅s | 40.3 Β΅s | 64.0 Β΅s | 82.5 Β΅s |
Latency is payload-insensitive up to 4 KB: Min rises 1.0 Β΅s across a 20Γ size increase. For context only (third-party, 2021, different hardware): gRPC C++ sequential RTT ~116β167 Β΅s over a Unix domain socket (MPI-HD, F. Werner).
π Measure your own hardware: 23_pubdatarate (throughput) Β· 30_publatency (latency)
π Full data and methodology Β· vs ZMQ/NanoMsg/NNG Β· Framework rankings
Embedded Linux on a 32- or 64-bit CPU -- ARM64, ARMv7, x86_64 and x86. If the target runs Linux with sockets and pthreads, Areg runs on it: NXP i.MX, TI AM62/AM335x, Rockchip RK3588, STM32MP1, Raspberry Pi, Intel Atom.
Measured with tools/intern/footprint.py, GCC 15.2.0, Release, on three
architectures -- x86_64 natively, ARM64 and ARMv7 cross-compiled with the toolchain files
the SDK ships. Framework code (text):
| What a device stores | x86_64 | ARM64 | ARMv7 |
|---|---|---|---|
shared libareg.so, stored once for every service |
1.26 MB | 1.18 MB | 0.74 MB |
| a self-contained service, static, logging off | 526 KB | 487 KB | 288 KB |
| a service binary against the shared framework | 43 KB | 42 KB | 26 KB |
mtrouter |
285 KB | 255 KB | 171 KB |
A 32-bit target is close to half the size of x86_64, and ARM64 within about 10% of it.
RAM, read from /proc on x86_64:
| What a process holds | Shared, logging on | Static, logging off |
|---|---|---|
| a service, resident | 6.6 MB, 7 threads | 5.6 MB, 6 threads |
mtrouter, resident |
6.5 MB, 9 threads | 5.7 MB, 8 threads |
| each connected client | ~7 KB -- ten clients cost under 1% of an idle router | ~6 KB |
-DAREG_LOGGING=OFF removes one thread and ~1 MB resident. Keep the shipped
net::*::tcpip::pairs = 0: raising it to 16 costs 1.8 MB and 32 threads before a single
client connects.
Not bare metal, not an RTOS and not 16-bit. Zephyr RTOS is planned after version 2.0.0 and does not exist today. ARM RAM is not published until it is read on an ARM board or runner -- an emulator reports its own memory, not the target's. No number here is scaled from another architecture.
π What "embedded ready" means, and where the line is
| Areg SDK | gRPC | DDS | |
|---|---|---|---|
| Service model | requests, attributes, broadcasts | RPC from .proto |
typed topics |
| Generated code | proxies, base classes, dispatch | stubs, service bases | types, readers, writers |
| Threading | calls run in the owning thread | yours to synchronize | yours to synchronize |
| Discovery | by service name | DNS or xDS resolvers | built in |
| Thread, process, network | same classes; the model decides | same stubs; you pick the channel | same API |
| Fault recovery | watchdog restart, reconnect | retries, health checks | liveliness QoS |
| Logging and tracing | distributed logs, viewer | OpenTelemetry plugin | vendor tools |
ZeroMQ, NanoMsg and NNG are messaging transports rather than service frameworks: see the transport benchmark.
Sources: gRPC name resolution Β· in-process channel Β· retry Β· health checking Β· OpenTelemetry; DDS (OpenDDS) discovery Β· QoS.
| Dependency | Minimum | Notes |
|---|---|---|
| C++ compiler | C++17 | GCC, Clang, MSVC |
| CMake | 3.20+ | Visual Studio solution included |
| Java runtime | 17+ | runs the code generator during the build |
| OS | Windows 10+, Linux, macOS | Cygwin and MinGW included |
| Python 3 | for agentic coding | runs the AI-agent tools; never needed to generate, build or run |
git clone https://github.com/aregtech/areg-sdk.git
cd areg-sdk
cmake -B build
cmake --build build -jBinaries are written to product/build/<compiler>/<os>-<bits>-<cpu>-release-shared/bin/.
Run 01_minimalrpc from there: a consumer finds the provider in another thread, sends a
hello request, the provider prints 'Hello Service!' and the application exits.
02_minimalipc runs the same components in two processes
through mtrouter. More: Build with CMake Β·
Visual Studio Β· WSL.
The Quick start script takes three modes: --mode local is one process
with two threads; --mode ipc is two processes through mtrouter, with a run.sh and
run.bat that start them in order; --mode pubsub is a local project whose
interface also declares attributes and broadcasts, which the consumer subscribes to.
Those are interface elements rather than an application type: an ipc project may
declare them just as well. Without --sdk-root, the project fetches Areg from
GitHub at configure time.
Other ways in: CMake integration for an existing project Β· all scaffolding options.
- 01_minimalrpc: multithreading. Provider and consumer in two threads, one process, no
mtrouter. - 02_minimalipc: IPC. The same components in two processes through
mtrouter. - 03_helloservice: one thread, then separate threads, then separate processes.
- 16_pubmesh: a mesh of local and public services discovering each other.
- 23_pubdatarate and 30_publatency: throughput and latency benchmarks on your hardware.
- 33_tempalarm: built by an AI agent. A monitor and an operator in two processes, attributes and broadcasts.
- 34_coffeemachine: built by an AI agent. A service driven by a generated state machine, in two processes.
- All examples
| Concept | Description | Example |
|---|---|---|
| Service interface | the API contract: data types, requests, responses, broadcasts, constants, in a .siml file |
PrinterDevice |
| Service | a named component instance implementing one or more interfaces | HP-Lab1 (implements ScannerDevice and PrinterDevice), Canon-Floor3 (implements PrinterDevice) |
| Consumer | declares which named service it depends on; notified when it appears or disappears | consumer of HP-Lab1 |
A consumer claims a service by name: "I need HP-Lab1." The framework connects them when
that service becomes available anywhere on the network, and notifies the consumer at once.
No polling, no manual connection management.
The provider and consumer classes are the same in every deployment. What changes:
| Deployment | Transport | What changes |
|---|---|---|
| Multithreaded (same process) | direct dispatch | only the model |
| Multiprocessing (same machine) | TCP via mtrouter |
the model per process; the interface is Public |
| Multi-device (network) | TCP via mtrouter |
as above, plus the router address in the configuration |
Areg is designed for controlled private networks: nodes are known, the network is trusted, and communication patterns are defined at design time.
- Mist layer: sensors, actuators and controllers form a local service mesh and resolve each other by name, with no central broker.
- Edge layer: gateways aggregate mist data, run local inference or control logic, and expose services to private infrastructure.
- Private infrastructure: servers and workstations process edge data, coordinate distributed workloads and host operator tools.
The same interfaces, generated code and operational model work at every layer.
Note
Areg is not for internet-facing communication: not a web server, REST endpoint or public MQTT broker. It works in trusted networks: industrial automation, scientific instrumentation, private distributed computing.
| Domain | Why Areg |
|---|---|
| Scientific and industrial imaging | multi-megabyte frames at ~2.7 GB/s (Windows) to ~6.5 GB/s (Linux) full-stack IPC on a laptop CPU; pipeline stages move between threads, processes and machines |
| Device-as-a-service | a device exposes its functions as a named service; hosts call it through a generated proxy, with no kernel driver |
| Industrial automation and robotics | watchdog restart, automatic re-registration and reconnection handle the faults that break hand-written IPC |
| Edge AI and inference | acquisition, preprocessing and inference change topology without touching their classes |
| Digital twins and monitoring | one interface for the device and its twin; consumers cannot tell them apart |
| Simulation and hardware-in-the-loop | a simulation registered under the real service name; regression tests in CI before hardware exists |
| Distributed C++ applications | ~2.0Mβ2.5M msg/s on one laptop replaces custom threading and IPC in backends |
More patterns, diagrams and limits: Use cases and benefits.
| Tool | What it does |
|---|---|
codegen.jar |
generates the service infrastructure from .siml and state machines from .fsml |
mtrouter |
routes messages between processes and machines |
logcollector |
collects logs from many processes, optionally recorded into SQLite |
logobserver |
captures, stores and controls log scopes from the console |
| Lusan | GUI for designing service interfaces, live log collection and log analysis |
AGENTS.md |
routes a coding agent to the docs and tools its task needs |
Libraries: areg (core framework), aregextend (extended utilities, SQLite wrapper), areglogger (log observer API).
Next, after 2.0.0:
- RTOS platform support, starting with Zephyr
Planned:
- Shared memory transport (zero-copy for same-machine IPC)
- Secure communication (optional TLS for
mtrouterconnections)
Open for community input:
- Extended networking protocols
- Language bindings (Python, Rust)
- Cloud-native deployment patterns
- WebSocket transport
- Installation and build: cross-platform builds, toolchains, packages
- Integration and configuration: CMake integration, FetchContent, build options
- Networking and communication: router setup, IPC, low-latency messaging
- Logging and monitoring: distributed logging for debugging
- Persistence: local data storage
- Development tools: code generator, Lusan, testing utilities
- Troubleshooting: common issues and solutions
- Examples and demos: sample projects catalog
- Performance and benchmarks: methodology, datasets, rankings
- HOWTO guide: practical development tasks
- AI agent guide: building an application with a coding agent
Areg SDK is released under the Apache License 2.0, a permissive license for open-source and commercial use.
Commercial support: enterprise licensing, training and dedicated support. Visit areg.tech or email info[at]areg[dot]tech.
- Issues Β· Discussions Β· Contributing guide Β· Wiki
- Built something with Areg? Open a discussion and tell us about it, and add the badge to your project:
Areg (Τ±ΦΥ₯Υ£) β Old Armenian: the Sun.


