By Zahi Raifer
Zahi Raifer has 23 years of experience in AI, Python, .NET and databases. He is the founder of Orivox, where he works on product development, not sales.
Disclosure: this article was drafted with the help of AI and reviewed by the author.
When people ask how Orivox edits customer websites, they usually expect the answer to be about the language model. This piece is about something less glamorous: how the system is split into processes, who owns which piece of state, and how those pieces change without breaking each other.
Orivox is two codebases running as four processes: the web app and its job worker, and the editing service and its worker. They share one Postgres database and one Redis, and they talk to each other only over HTTP.
That last rule matters most. There is no back door where one codebase reaches into the other's internals. If the web app needs something from the editing service, it asks over HTTP, through a contract both sides agree on.
Edit turns and other long work go through job queues backed by Redis. A web request never waits on a model, so a slow model call cannot tie up the site.
When an owner types a request, the web app checks the account, queues the turn and takes the project lock. The workers do the slow part. The request that accepted the turn has already returned.
| State | Owner | Why one owner |
|---|---|---|
| Each project's Git history | The editing service | Every turn is a commit, with one authoritative history. |
| The chat transcript | The editing service | The web app sends only the latest message; there is one copy of the conversation. |
| Accounts, credits, publishing, domains | The web app | Publishing is a business decision (plan, domain, billing), kept with the business data. |
| The project lock | Shared, in Redis | Held for a whole turn by whoever is writing. |
The transcript is a good example. The web app does not keep its own copy of the conversation and replay it; it sends only the newest message. There is nothing to drift out of sync because there is only one copy.
The same goes for history. The web app never runs Git against a project. When it writes files itself, it takes the lock, writes, and asks the editing service to commit. Ownership is not a guideline here; it is the only path the code offers.
Because the two codebases depend on each other only through HTTP, the order of releases follows the dependency: the editing service first, then the web app that calls it.
A change to the contract between them is made additive first, released, and only then used. The new field or endpoint exists before anyone relies on it, so there is never a moment where the caller expects something the callee does not yet provide.
Those contracts are pinned by tests on both sides, and every live failure becomes a replay test. A boundary that is tested from both ends is much harder to break quietly.
The separation continues into production. Production runs on two identical servers, one active and one standby, and there are separate traffic switches for the web app and for the editing service. One service can be released or rolled back without touching the other. That only works because the services already treat each other as separate parties with a contract between them.
None of these rules is clever. Single ownership, HTTP-only boundaries, queues instead of waiting, additive contract changes, tests on both sides. Each is enforced by code rather than by care, so they hold on a busy day as well as a quiet one. That is most of what keeps Orivox stable.