Skip to content

Basics of modern backends

Delta AI generates systems with a particular shape: small services, explicit boundaries, asynchronous events where possible, and stateless compute. This page explains the reasoning behind that shape so the output makes sense.

You do not need this page to use the product. It is here so the generated architecture is legible rather than opaque.

Each stateful service owns its own logical database. No service reads another’s tables. When one service needs another’s data, it calls an endpoint or consumes an event.

This is what makes services independently deployable. A shared database makes every schema change a coordinated release.

Synchronous for decisions, asynchronous for effects

Section titled “Synchronous for decisions, asynchronous for effects”

A request that must be answered before the caller can continue is synchronous. A consequence that can happen slightly later is an event.

Interaction Style Why
“May this user post here?” Synchronous The caller cannot proceed without the answer
“A message was created” Asynchronous Delivery, notifications and metrics can lag
“A member was banned” Asynchronous Enforcement across services can converge

The generated services use a transactional outbox for the asynchronous side: the event is written in the same transaction as the state change, then relayed. That avoids the classic failure where the database commits but the event is lost.

Services keep no durable state on the instance. Everything that must survive a restart lives in PostgreSQL, Kafka offsets, or an external provider.

That is what makes horizontal scaling trivial and restarts safe. It also means the generated services are standard container images — how you orchestrate them is your choice.

Every generated service exposes:

  • GET /healthz — liveness. Never probes dependencies.
  • GET /readyz — readiness. Fails when a dependency is unavailable or the service is draining.

The distinction matters: a liveness probe that checks the database will restart a healthy service during a database blip. Readiness is where dependency checks belong.

When a service cannot verify that a caller is allowed to do something, it denies. It does not fall back to allowing.

This is why the generated access checks have short timeouts and bounded retries, and why an unavailable authorization service produces a 503 rather than a permissive default.

The generated systems use PostgreSQL and Kafka because they are widely available, well understood, and easy to run anywhere. They are not the only correct choice, but they are the choice least likely to trap you.

The generated repositories contain the full reasoning, not just the outcome:

  • docs/architecture.md in each service — boundaries and failure modes
  • docs/decisions/ — architecture decision records with alternatives considered
  • The system design repository — the whole-system view