Emil Erofeevskiy 1998-As long as possible | All Rights Reserved
ChatGPT&Gemini are good extensions for my brain
Recently, I started working on what has become the most technically demanding project of my life.
I actively use C++ to translate ideas into practical systems and tools. My previous major project was FantomChat. This time, I wanted to go further.
As a Backend / Reliability Engineer, I have always been curious about what it actually takes to build systems that survive real pressure — the kind of pressure handled by platforms like YouTube or Google. Not just in theory, but in architecture, execution model, and behavior under load.
This project is where that curiosity turned into something concrete.
I didn’t start building AdequateAPI because existing frameworks were bad.
I started because I wanted to go deeper than my environment required.
Work gives you boundaries.
University gives you boundaries.
Most projects give you just enough surface to stay productive.
But they rarely force you to understand:
how coroutine frames are allocated
what actually happens when you co_await
how ABI mismatches can corrupt memory
how thread pools interact with lifetime
what “async” truly means under the hood
AdequateAPI was not born from frustration.
It was born from curiosity.
At first, it was just an attempt to dive into modern C++:
Coroutines
Boost.Asio
Boost.Beast
PostgreSQL
Explicit dependency injection
Structured project layout
The goal was simple:
Build something useful while learning deeply.
Then something changed.
The example code started turning into a structured system.
Core abstractions emerged:
core/ as a stable extension surface
clear separation between Controller → Service → Repository
explicit execution domains
explicit offloading model
Execution domains became explicit.
At some point, it stopped being a playground.
It became a tool.
The turning point wasn’t a feature.
It was understanding causality.
When I ran into:
Coroutine Frame ABI instability (layout mismatches between translation units)
coroutine lifetime issues
invalid free
memory corruption under offload
GCC 11 coroutine instability
I didn’t just fix bugs.
I was forced to understand:
Coroutine frames live on the heap
co_await generates a state machine
Offloading CPU work can break ownership boundaries
Compiler versions matter for coroutine codegen
ABI is a real contract, not an abstraction
It took weeks of research.
First — confusion.
“How is this even possible?”
Then investigation.
Then architecture changes.
Then rebuild in a clean container.
Then upgrading to GCC 14.
Then stabilization.
And finally — relief.
Not because the code worked.
But because I understood why it worked.
That moment felt like reaching a summit.
Most frameworks abstract async away.
But async is not magic.
It is a state machine that:
stores suspended execution state
captures variables
allocates coroutine frames
resumes execution later
If you offload incorrectly, you can:
access freed memory
move coroutine frames across threads unsafely
break ownership contracts
corrupt allocator state
One of the most dangerous traps here is lambda capture lifetime. When you offload a task, you must ensure that all captured data remains valid until the task actually completes. In a coroutine world, co_await creates a suspension point where the local context might effectively outlive the objects it references if they were captured by reference. This is why AdequateAPI emphasizes explicit ownership (using std::move or shared pointers) in offload boundaries.
In AdequateAPI, offloading became an architectural boundary.
Example:
CPP
// Example: explicit CPU offload
// Look into: core/helpers/Offload.h
// The coroutine suspends here, freeing the IO thread,
// and resumes strictly in the IO executor once the pool finishes.
auto result = co_await async_offload(
blocking_pool.get_executor(),
[data = std::move(input)]() {
return heavy_hashing(data);
}
);
The key idea:
The coroutine remains in the IO executor.
The heavy task runs elsewhere.
Ownership is explicit.
No implicit thread migration.
I didn’t “discover async”.
I deepened my understanding of it.
I understood that:
Async is a state machine, not magic.
Multithreading is structured hardware utilization.
Network IO switching happens at the OS level.
Lifetime is more important than syntax.
Offloading is an architectural boundary.
Async is not about speed — it’s about resilience under load.
That last one changed everything.
Async does not make a request faster.
It makes systems survive pressure.
That realization reshaped how I look at backend architecture.
Request flow is intentionally simple:
Client
↓
HTTP (Beast)
↓
Router
↓
Controller
↓
Service
↓
Repository
↓
Database
No reflection.
No implicit magic.
No hidden thread pools.
Details: https://github.com/Emilianissimo/adequate-api-cpp/wiki/Project-Layout
AdequateAPI is not about automation.
It is about guarantees.
The core guarantee I strive to provide:
When using the core components correctly, request/response lifetime remains safe under async IO and CPU offloading.
This means:
No hidden ownership
No silent thread hopping
Explicit offload boundary
Session lifetime bound to request lifecycle
Strict control over the coroutine resumption point (no unexpected context switches)
This is still being hardened.
That’s why the current version is 0.9.0.
I prefer review over premature feature expansion.
AdequateAPI is not for everyone.
It’s for developers who:
Want predictable behavior
Prefer explicit concurrency
Understand ownership and lifetime
Accept responsibility for architecture
It does not promise magic.
It provides a foundation.
After that, the responsibility is yours.
It’s about:
Clear structure
Deterministic execution
Causal understanding
If you don’t understand cause and effect in concurrency,
no framework will save you.
Even with ChatGPT or Gemini, without background knowledge, this architecture would not have emerged.
This wasn’t lifting knowledge from zero.
It was deepening it.
AdequateAPI is not about C++.
It’s about the desire to go deeper than your environment demands.
And to build something useful while doing so.
I didn’t want to write “a framework.”
I wanted to bring value.
If it helps even a few engineers avoid architectural mistakes —
then the journey was worth it.
I would love to have your opinion and critisism here: https://github.com/Emilianissimo/adequate-api-cpp/issues
My goal is not to stroke the ego (just a bit), but to provide and build.
And my plans are going far away beyond this theme.
Until then, loves.
Pages — https://emilianissimo.github.io/adequate-api-cpp/
Github — https://github.com/Emilianissimo/adequate-api-cpp
Emil Erofeevskiy 1998-As long as possible | All Rights Reserved