ObjectOS

Architecture

What you're actually running — for the engineer evaluating whether to bring this in.

A practical view of what runs on your machines when you deploy ObjectOS, what data leaves your network, and what doesn't.

The mental model is two thin layers:

  1. Metadata — packages of objects / views / actions / flows / agents. Mostly written by the AI Builder against a sandboxed tool API; sometimes hand-edited, always version-controlled and audited.
  2. A single Node.js runtime that interprets that metadata into a working application — REST API, Console UI, permissions, jobs, AI tools — all in one process, talking to your database.

No code generation step, no deploy pipeline between "user described what they want" and "it's live". The runtime hot-loads the new metadata after a HITL approval.

What you deploy

One Node.js process, serving one app. That's it.

┌─────────────────────────────────────────────────────┐
│                  ObjectOS process                   │
│  ┌───────────────────────────────────────────────┐  │
│  │   HTTP dispatcher  (/ · /api · /_console …)   │  │
│  ├───────────────────────────────────────────────┤  │
│  │   ObjectKernel — this deployment's app        │  │
│  │   ├─ Auth (Better Auth)                       │  │
│  │   ├─ Security (RBAC + row-level + field)      │  │
│  │   ├─ ObjectQL (data engine, generates SQL)    │  │
│  │   ├─ REST API generator                       │  │
│  │   └─ Capabilities loaded per artifact         │  │
│  │      (audit, storage, jobs, queue, AI …)      │  │
│  └───────────────────────────────────────────────┘  │
└──────────┬──────────────────────────────────────────┘


   Your business database
   (Postgres / MySQL / SQLite / Turso / MongoDB)

It's a single statically-linked binary's worth of complexity. No sidecar, no Kafka, no separate cache layer required. Add those when you need them; don't pay for them on day one.

A deployment serves one app. Which app is a deployment-level decision — see Boot modes — and it is the same app for everyone the deployment serves, including a walled deployment where several organizations share it. You grow the deployment by running more identical replicas of the same process, not by packing more apps into one; see Docker.

Where your data lives

DataLives inLeaves your network?
Business recordsYour databaseNo
User accounts, sessions, OAuth tokensYour databaseNo
Audit logYour databaseNo
Settings, API keys, secretsYour database / secret managerNo
Uploaded filesYour disk or your S3/R2 bucketNo
The compiled app definition (objectstack.json)A file on disk or fetched from your control planeOptional

ObjectOS does not call home. No telemetry. No license check. If you cut internet access entirely, it keeps running indefinitely. See Air-gapped.

How a request is served

1. Ingress / TLS termination      (your load balancer)
2. HTTP dispatcher                (security headers, request id)
3. AuthPlugin     — session cookie, bearer token, or API key
4. SecurityPlugin — RBAC + row-level + field-level checks
5. Route handler  — generated REST, declarative action, or custom
6. Data driver    — ObjectQL compiles to SQL / Mongo query
7. Response with X-Request-Id propagated

The app is already resolved before the first request arrives: the kernel is built during startup, and the process does not report itself ready until it is. So a served request carries no step that decides which app it belongs to, and there is no per-app warmup for a reader to plan around — what a request costs is authentication, the permission checks, and one compiled query.

The three layers (only matters if you're integrating)

Most customers deploy only ObjectOS. The other two layers exist if you want to know where the artifact comes from:

LayerWhat it isWhere it runs
Framework (@objectstack/*)Open-source kernel, ObjectQL, plugins, driversnpm — pulled in at build time
Control plane (optional)Publishes compiled objectstack.json artifacts; you can use the hosted ObjectOS Cloud, run your own, or skip it entirelyYour CI, our cloud, or your laptop
ObjectOSThe runtime you operateYour infrastructure

If you're shipping a single app, you don't need a control plane — compile objectstack.config.ts → dist/objectstack.json in your CI and ship the JSON in the image. If you publish apps that several deployments install, the control plane is where that catalog lives.

Boot modes

Where the running app comes from is one decision, and the deployment declares it. The shipped default needs no configuration; each of the other modes is selected by naming a published artifact, and the Environment Variables reference carries the exact contract for each.

ModeWhenHow the app arrives
Config-authoredThe shipped shape. Single app, evaluation, air-gapped, most production deploymentsThe runtime boots the metadata authored in the image, plus anything installed into it
Artifact-pinnedThe app is released on its own cadence, separately from the runtime imageOne variable names a published artifact by URL, with an optional integrity pin. Upgrading the app is a change to that variable plus a restart
ComposedSeveral organizations behind the isolation wall, sharing one database, running a published app — the hosted single-app SaaS shapeThe same artifact reference, consumed from the deployment's own configuration so the enterprise plugins load alongside it. Air-gap licensed only, and refused at startup otherwise

Whether the deployment also talks to a control plane is a separate decision, made by the cloud-posture variable — a connected deployment can be any of the modes above. A self-hosted runtime authenticates to a control plane with a token minted when the deployment was bound to it, not with a key pasted into a file, and pairing the wrong licence mode with the wrong cloud posture is refused at startup.

Performance characteristics

This page publishes no latency or memory figures. What you run is a digest-pinned image serving your app against your database, and the only numbers worth sizing a deployment against are the ones you measure on that. What this page can give you is the shape — where each cost comes from, and what to measure it as.

CharacteristicWhere it comes from, and how to measure it
StartupThe process starts, builds the kernel for this deployment's app, and only then reports ready. Measure it as time to a 200 from /api/v1/ready on your own image and artifact; a larger app and more loaded capabilities give it more to do.
Request latencyAuthentication, the permission checks, and one query compiled by ObjectQL. Nothing per-request resolves which app to serve, so the database round trip is the part that usually moves; measure it at your own percentiles, against your own data volume.
MemoryOne resident copy of this deployment's metadata, plus the capabilities the app loads — they are optional plugins, so a deployment that loads fewer holds less — plus whatever your concurrency has in flight. Measure the container's RSS under your own load, not at idle.
Growing past one processReplicas of the same process, each serving the same app. Past one replica the cluster driver and identical shared secrets stop being optional — see Docker.

Why this shape

  • One Node process, no sidecars → fits in a docker run, fits in a systemd unit, fits in a long-lived container or VM.
  • One app per deployment → the metadata is resolved once at startup rather than per request, so there is no cache sizing to get right; where several organizations share a deployment, they share its app and the isolation wall between them is enforced inside the runtime.
  • Generated APIs on top of declared metadata → there's no codegen step in your CI, no client SDK to publish; the API matches your data model by construction.
  • All capabilities are optional plugins → image size scales with what you actually use.

Where to go next

On this page