← Back to home
12 min readv0.1 Final

ARC System Principles

Arda Akgür

SystemsArchitecturePrinciplesEngineering

This text does not claim to explain how to build perfect systems. I do not believe perfect systems exist.

These are principles I earned over years of building systems, writing code, teaching students, and watching working systems fail.

For me, systems engineering is problem-solving before it is technology selection.

1. The most important thing in a system is stability
Whatever fundamental logic you used to build a system, do not keep rewriting that logic once the system is running.

Parameters can change. Small improvements can be made. Bugs get fixed. But if you start rewriting the system's core rules in the middle of the road, after a while you will have neither the original design nor the new one.

When a major change is truly needed, sometimes the right move is not to force the current system — it is to start a new version.

Do not change the rules of the game in the middle of the game.

2. Build the simplest system that works
Do not spend day one designing for millions of users, five-year scale, and problems that do not exist yet.

That is usually not engineering. That is YouTube architecture.

Build the understandable system that solves today's problem as quickly as possible and actually works.

If you one day hit a real scale problem, that is a good problem. It means the system lived long enough to get there.

When V2 is needed, you can build V2 differently.

3. Stay away from the status quo
The fact that everyone uses a technology or architecture does not mean it is right for your problem.

"Industry standard says so" is not a technical justification by itself.

Define the problem first. Then look at what solves that problem best.

If the answer is what everyone uses, use it. If not, do not be afraid to do something different.

Be loyal to the problem, not to the tools.

4. Do not make important decisions while hungry or exhausted
An architect's most important tool is not the computer. It is the mind.

Hunger and serious fatigue can destroy decision quality. A solution you would normally reject can suddenly look good enough. You may take unnecessary risk, get irritated easily, or accept a wrong decision just to finish the work.

Sometimes the state can even feel intoxicating. You believe you can still decide — but judgment has already collapsed.

In those moments you can do routine work. You can write code, run tests, inspect logs. But do not make expensive architectural decisions if you can avoid it.

If a decision can wait until morning and you are depleted, let it wait until morning.

Hunger and fatigue are your enemies.

Before the system can be designed, the architect must be operational.

5. If the code changes, the documentation must change
With every meaningful code update, update the documentation too.

Do not treat documentation as a separate chore for after the work is done. Code and documentation are two halves of the same change.

Modern AI tools make this far easier than it used to be. After every important change, have AI review the change and the related code. Generate Markdown that describes the system's current state, or update what already exists.

Keep documentation in the repository as `.md` whenever you can. Markdown is simple, tracks cleanly in version control, and renders well on GitHub.

If a backend change affects the frontend, share the relevant Markdown with the frontend team.

A frontend developer should understand how an endpoint works, its request and response shape, changed behavior, and caveats — without having to dig through code first.

The same principle applies across teams and services.

AI accelerates documentation. Responsibility for correctness still belongs to the engineer who made the change. Do not accept AI-written docs as truth without checking them.

If the code was updated and the docs were not, the work is not finished.

Documentation is the system's memory.

6. See the finished system in your head first
Before you start writing code, you should be able to see the finished system in your mind.

If you cannot, take a pen and paper and draw.

It does not have to be an ER diagram. It does not have to be UML. It does not have to match anyone's standard.

Draw boxes. Draw arrows. Write notes beside them. Draw however it makes sense to you.

Beauty is not the point. Being able to see the whole system is.

If you try to discover a system you cannot see by coding your way through it, you start designing and implementing at the same time.

See first. Build second.

7. Do not forget who the system is for
Do not dismiss the ideas of non-technical managers and users.

Sometimes an idea that feels technically strange is looking at the problem from an angle you never considered.

Their job is not to think like you.

Your job is to understand what they want and, when possible, turn it into a working system.

Listen to their dreams and try to make them real. Sometimes the result will genuinely surprise you.

Build the system for the people who will use it — not for yourself.

8. The architect must not lose control
Every serious system needs fail-safe mechanisms.

You should be able to stop the system with a single environment variable when needed. Have a controlled management endpoint if required. Design paths to disable critical pieces.

These must not be insecure secret backdoors. They should be authorized, secure, and preferably logged.

No matter how autonomous a system becomes, the architect must never become a spectator of their own system.

Final control stays with the architect.

9. Suspect your own mistake first
When the system slows down, do not immediately blame the hardware.

Maybe there is a deadlock you cannot see. Maybe you wrote a bad query. Maybe there is an unnecessary network call. Maybe an architectural mistake is locking the system.

Yes — hardware can truly be insufficient.

But measure first.

An engineer must be able to accept that they can be wrong. There is nothing shameful in that.

A person who cannot admit they were wrong also cannot fix their mistake.

10. Raise students
Do not let the system live only inside your head.

Teach the system to your students.

If you are not there tomorrow, the system must still continue. Letting someone else understand and improve it does not shrink your authority. It proves you are a good architect.

A system only one person understands is not strong. It is fragile.

Transfer the knowledge.

11. Work with a small, aligned team
Do not be a lone architect. Do not build an unnecessarily large team either.

Work with people who are open to learning, who listen, who ask questions, and who have not lost the spirit of a student.

Criticism is valuable. A junior can see the bug you missed. Listen to them.

But people who turn constant opposition into a work style are dangerous while building systems. Re-litigating every decision endlessly forces the architect to keep changing direction and eventually wrecks stability.

Debate until the decision is made.

Once it is made, execute as a team.

You do not have to work long-term with someone who constantly blocks progress through opposition.

12. Be creative, but stay simple
An experienced engineer looking at a good system should be able to say "wow."

And a good junior entering that same system should understand roughly what is going on within about a week.

Those two things are not opposites.

True mastery is not using a hundred services or inventing abstractions nobody understands.

It is solving a complex problem with a surprisingly simple system.

Complexity is not craftsmanship.

13. Do not stuff every new idea into the old system
When a new idea arrives, your first reflex should not be to bolt it onto the current system.

Sometimes you need a new service. Sometimes a new application. Sometimes you genuinely need V2.

If you try to extend the old system forever, you eventually pile years of decisions and exceptions on top of the simple system you started with.

Sometimes starting from zero is cheaper, cleaner, and more correct.

Change does not always mean growing the current system.

14. Use artificial intelligence as a tool
AI can seriously strengthen a system.

Modern reasoning engines in particular are powerful both while building the system and at runtime.

They can review code, find edge cases, support decisions, understand natural language, and solve ambiguous problems where classical algorithms struggle.

But do not dump everything on AI.

If a simple deterministic solution is enough, use it. If reasoning truly adds value, use AI. If they work better together, build a hybrid.

Give AI work. Do not give it authority over the system.

15. Do not expect miracles from AI
AI is only as smart as the person using it.

If you describe the problem badly, even a very strong model can produce the wrong solution very quickly.

You need to know what you want. You need to understand the problem well enough to evaluate the answer. You need to notice when it is wrong.

AI does not have to be the engineer instead of you.

Used well, it expands your engineering capacity.

Do not expect miracles.

16. Habits stick, shit smells
It is what it is.

Do not hunt for deep meaning in everything.

Sometimes a bug is just a bug. Bad code is bad code. An idea that does not work does not work. A wrong decision is a wrong decision.

If a simple explanation is enough, do not decorate the problem with unnecessary theory.

Look at the reality in front of you first.

17. Do not fear imitating the master
As a student, you do not have to invent everything.

When I was a student, I rewrote structures like ArrayList from scratch in order to learn. The goal was not to invent a new data structure.

The goal was to do what the masters did myself, understand how it worked, compare it with my own solution, and grow.

Learning by imitation is not plagiarism.

First reach the level where you can do what the master did. Try to understand why they did it that way. Then question it. Then develop your own method.

Rejecting what you do not understand just to be different is not creativity.

Learn first. Break later.

Closing
Good systems engineering is not the art of using as much technology as possible.

It is understanding the problem, seeing the solution in your head, building as simply as possible, protecting the stability of what works, and being able to admit your own mistake when needed.

A good architect knows the state of their own mind first. Declining major decisions while hungry, exhausted, or unable to think clearly is itself part of engineering.

They protect the system's memory as carefully as the code. They document what they change and share that knowledge with the people who will keep building the system.

They control their system — they do not worship it.

They lead their team — they do not silence their students.

They use artificial intelligence — they do not outsource thinking to it.

They learn from what was done before — they do not surrender to the status quo.

And most important of all: if the system works, they try to understand why it works; if it does not, they try to understand why it does not.

Everything else is a tool.

Arda Akgür
ARC System Principles
v0.1 Final