Skip to content

Limits and Non Goals

Daniel Hokanson edited this page Aug 30, 2026 · 1 revision

Every other page on this wiki describes what Forge does. This one describes where it stops: the shape of install it is built for, the things it deliberately does not try to be, and the places where the current build ships a working screen in front of something that is not yet connected. Forge is in public beta, so some of what follows will move — but the architectural limits below are structural, not roadmap items, and knowing them before you commit is worth more than a feature checklist.

The scale envelope

Nothing in the repo states a user count or a record ceiling, and inventing one would be dishonest. What can be stated is the architecture, which is what actually sets the ceiling:

  • One PostgreSQL instance. The compose stack defines a single database service with a single data volume. There is no read replica, no connection pooler in front of it, no sharding and no partitioning strategy.
  • Background jobs run inside the API process. Hangfire is registered as a server in the same container that serves HTTP, with its storage in the same PostgreSQL database. Recurring work — backups, digests, reorder analysis, sync jobs — competes for the API container's CPU and memory.
  • SignalR has no backplane. Hubs are registered plain. The only Redis anywhere in the deployment belongs to the crash-reporting sidecar, and is not wired to the API. Several caches (the capability snapshot, session validation, base currency) are in-process memory.

Together those mean Forge runs as a single API instance, and it grows vertically. Adding a second API container would split real-time clients across instances that cannot see each other's messages, and each compose service is pinned to a fixed container name, so there is no supported scale-out switch to flip. The growth path is a bigger box, and then moving PostgreSQL and object storage onto their own host — see the split-topology section of Installation.

For a shop of a few dozen people on one site this is a feature: one stack, one backup, one thing to watch. For a multi-site operation with hundreds of concurrent floor users it is the constraint to test against before committing, and it is why there is no high availability or failover story — recovery from a lost box is a restore, not a cutover. See Backup and Restore.

There are also no Kubernetes manifests and no Helm chart. Docker Compose is the deployment unit, on purpose.

One install is one company

No entity in the domain model carries a tenant identifier. Forge is single-tenant by construction: one install serves one legal entity. You get multiple sites through company locations with their own working calendars, and a configurable base currency — but two companies that need separate books mean two stacks, with their own databases, backups and upgrade cycles. Decide that before data entry starts, because there is no later split.

It does not read your machines

This is the first question most MES evaluators ask, and the honest answer is no. Forge models the configuration — a machine connection carries an OPC UA endpoint, a security policy, credentials, a poll interval and a set of tags hanging off a work centre — but the only implementation of the machine-data service is a mock, and it is the one registered in every posture. Connections, tags and their test action resolve against fabricated values. There is no collector behind the configuration.

What is real is everything downstream of human and application input. OEE, the six big losses and the downtime reporting are computed from production runs, downtime logs and the working calendar — records people and the app create. That is a genuine capability, and it is entirely different from reading a signal off a controller. If your evaluation depends on automatic data capture from equipment, Forge does not do it today.

Integrations that are shape rather than connection

Configuration and Integrations is the full picture, including which connectors are real and how to tell what your own box is running. The limits worth naming here:

Area Where it actually stops
Bank payment origination Placeholder. Forge records payments; it does not originate ACH or wire transfers.
CPQ Placeholder — the interface and screens exist, the engine does not.
Machine data / IoT Placeholder, as above.
BI export The API-key scheme, the read-only route prefix and an identity probe exist; the entity-export endpoints do not yet. Use the per-domain CSV/XLSX exports or the full database dump — see Data Ownership and Export.
Several inventory and maintenance analytics services Placeholder: consignment, ABC classification, pick waves, drop-ship, back-to-back, kanban replenishment, project accounting, cost of poor quality, predictive maintenance. Working screens, fabricated numbers.
EDI The X12 translator is real. The transport is SFTP only; partners configured for AS2, VAN, email or a partner API fall through to a manual channel, meaning you move the files by hand.
E-commerce Shopify and WooCommerce are real connectors. The marketplaces are deliberately unregistered and raise a clear error rather than pretending to poll.
Multi-currency The base currency is a real setting and amounts are recorded with their own currency. Conversion is not implemented — exchange-rate lookup, conversion and exchange gain/loss are stubs, and the UI surfaces the ISO code on a mismatch instead of converting.

The durable way to check any of this on your own install: the readiness report tells you which capabilities you enabled but never finished wiring, and the API's service registration is the authoritative catalogue of what is real. A capability being on does not mean the thing behind it is connected — see Capability Gating.

Outbound webhooks are half-built

An admin can register a webhook subscription today: a URL, a list of event types, a signing secret held encrypted, extra headers, a failure threshold that auto-disables the subscription, and a delivery-history view. Nothing sends them. The integration outbox dispatcher implements delivery for email and returns a not-implemented error for the webhook provider, so no delivery is ever attempted and the history stays empty.

Machine-to-machine integration today therefore runs in two directions only: you call Forge, or you push into Forge through an inbound webhook such as carrier tracking or call logging. Do not design around receiving events from Forge yet. The domain-event vocabulary those subscriptions will eventually speak already exists, which is why the admin surface is there — but it is a placeholder for a dispatcher, not a dispatcher. API Access covers what does work: tokens, API keys, idempotent writes and the real-time hubs.

Offline is narrower than it sounds

The browser and installed web app cache the shell and recent reads, so Forge opens and shows data without a network. Saving offline is the native mobile shell only, and only for a fixed set of floor actions. Mobile and Offline states exactly which.

Do not trust the comparison document in the repo

The umbrella repo carries docs/industry-comparison.md, a scored comparison against ten named ERP products. It is dated, and it is stale in both directions. Its closing "critical gaps" list names MRP, SPC, CAPA and NCR, EDI, OEE, multi-currency and MFA as things Forge lacks — all of which have since shipped as feature areas with their own capabilities. Meanwhile the real current limits on this page, machine data most of all, do not appear in it at all. Read it as a snapshot of an earlier build, not as a statement of what Forge does or does not do today.

For a current answer, two sources beat any document: the capability catalog in forge-api, which is the authoritative feature list (Capability Gating), and your own install's admin screens and readiness report. Feature Reference indexes the per-domain documentation, with the standing caveat that where a doc and the code disagree, the code wins.

Clone this wiki locally