SolomonGraph

Single-tenant graph infrastructure

Your data is already a graph. Standing one up shouldn’t be a project.

SolomonGraph is one machine image. Launch it into your own AWS account, declare what your objects mean, and POST the JSON your systems already emit. You get a property graph you can walk in Cypher — with no cluster, no coordinator, and nothing leaving your VPC.

Buy a licence Read the documentation £2,499/year · 30-day refund
Deployment
One image, your account
Operations
No cluster to run
Data egress
None, by construction
Interface
Cypher in, JSON out

The question is easy.
Getting to the answer is the project.

Which customers does a single plant outage reach. What did Thursday’s deploy take down four services away. Which accounts sit three hops from a name on a sanctions list.

The answers already exist in your data. They are spread across systems that were never designed to be walked end to end, so you pick one of three, and all three cost more than the question is worth.

Write the SQL

Recursive CTEs and self-joins that gain a clause every quarter. It works, right up until the person who wrote it leaves and nobody will touch it.

Run a cluster

The right data model on the wrong operating bill. You are now tuning heap and carrying a pager for a query you run on Thursdays.

Hand it to a vendor

Fastest to start, and your records now live in someone else’s account. The security review outlasts the integration by a month.

SolomonGraph is the fourth option. The data model, on one machine, in your account, with nothing to operate.

Nesting is how data arrives.
Direction is what it means.

A deploy record arrives nested inside the incident that it caused. Causation runs the other way. Every tool that infers edges from document structure gets this backwards, and no query you ever write will warn you.

So you say it out loud, once, in the ontology. Change one word and watch the meaning invert while the payload stays byte-for-byte identical.

The document you POST — unchanged

{
  "id": "INC-42",
  "summary": "checkout 500s",
  "deploy": {
    "id": "D-9",
    "sha": "a1b2c3"
  }
}
// the deploy is nested inside the incident

What you declared it to mean

"incident": {
  "relationships": {
    "deploy": {
      "edge": "CAUSED",
      "direction": "in"
    }
  }
}

The edge you get

CAUSED Deploy D-9 Incident INC-42 the deploy caused the incident

Correct. Causation runs from the change to the failure, against the way the document nests. This is the edge your on-call engineer needs at two in the morning.

Declare it. Send it.
Walk it.

  1. Declare

    Objects become nodes, relationships name the edge and its direction. Your domain, your nouns. This is the only part that needs thought.

  2. Ingest

    Nested documents, flat foreign keys, bare identifiers. All accepted, in any order, because references that arrive early become stubs that fill themselves in later.

  3. Traverse

    Cypher over HTTP, against a graph that means what you said it means. A fortnight of SQL becomes four lines.

PUT /ontology/document
{
  "service": {
    "key": "name",
    "properties": {
      "name": "string",
      "tier": "string",
      "team": "string"
    },
    "business_context": "A deployable unit. Services
       depend on other services, so the edge is self-referential.",
    "relationships": {
      "service": {
        "edge": "DEPENDS_ON",
        "direction": "out",
        "id": "name"
      }
    }
  }
}
POST /ingest
curl -X POST $HOST/ingest \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"type":"Incident","data":{
       "id":"INC-42",
       "severity":1,
       "deploy":{"id":"D-9","sha":"a1b2c3"},
       "service":"checkout"
     }}'

→ {"nodes_written": 3, "edges_written": 2,
     "stubs_created": 1, "warnings": []}

# "checkout" is a bare reference. It becomes a stub
# now and a full Service node when that record lands.
POST /query
-- who is downstream of what this deploy broke?
MATCH (d:Deploy {sha: "a1b2c3"})-[:CAUSED]->(:Incident)
      -[:DEGRADED]->(s:Service)
MATCH (x:Service)-[:DEPENDS_ON*1..3]->(s)
RETURN DISTINCT x.name, x.team, x.tier
ORDER BY x.tier

One mechanism.
Your words.

There is no retail edition and no healthcare edition. There is one engine and one ontology format, and the sector is a file you write in an afternoon. Change the tabs below and watch what actually differs between industries: only the nouns.

Which first touch actually paid for itself?

Why it is hard todayAttribution lives in four tables and one of them is a session log that nobody has ever joined to revenue.

Ontology fragment
"order": {
  "relationships": {
    "session": {"edge": "PLACED_IN",
                 "direction": "out"},
    "basket":  {"edge": "CONVERTED_FROM",
                 "direction": "out"}
  }
}
The question, in Cypher
MATCH (o:`Order`)-[:PLACED_IN]->(s:Session)
WHERE s.medium = "paid"
RETURN s.campaign,
       count(o)      AS orders,
       sum(o.amount) AS revenue
ORDER BY revenue DESC

Six sectors. One engine, one API, one ontology format. The only thing that changed was the file you wrote.

History that repairs itself.

Some relationships are mutually exclusive from their source. A person has one lifecycle stage, an order one status, a subscription one plan. Declare that, and the graph keeps its own history: a new edge closes the old one with a valid_to rather than deleting it, because how long were they a lead is a question only the closed edge can answer.

One node, three intervals

lead      2026-01-10  2026-03-05
customer  2026-03-05  2026-06-01
lead      2026-06-01  open

# Re-entry needs no special case. A churned account
# reactivating is simply another interval, and nothing
# in the model has to be undone.

Then February’s event turns up after June’s. Nothing gets patched. The whole timeline for that node is recomputed — sort the intervals by start, set each one’s end to the next one’s start, leave the last open — so the late record sorts into place and its neighbours correct themselves.

Replaying a feed changes nothing. That is the difference between a system that records events and one you can hand to an auditor.

The sharp edge, said out loud: raw Cypher returns closed intervals too, so aggregations over an exclusive edge will double count unless you filter on valid_to IS NULL. It is in the documentation under Limits and gotchas, not in the small print.

A model can write Cypher.
It cannot guess what your edges mean.

This is the part that makes the ontology worth more than the graph. Every object you declare carries a business_context — plain English, stored next to the schema, saying what the thing is and why anyone cares. Point a model at GET /ontology and it receives the nouns, the verbs, the direction of every relationship and the reason each one exists.

Grounding

Retrieval over a typed graph returns a path, not a paragraph. The path is the citation, and a reviewer can walk it node by node to see why the answer is the answer. That is a materially different conversation with a risk function than “the model said so”.

Multi-hop

Language models are poor at joins and excellent at questions. Let the graph do the traversal and the model do the asking, and the failure mode moves from silently wrong arithmetic to a query that either runs or does not.

Provenance

Exclusive edges record when each fact was true, with intervals rather than overwrites. An agent’s decision in March can be re-examined against the state of the world in March.

Not yet

There is no MCP endpoint. Today an agent calls /query over HTTP with a bearer token, which is what most frameworks want anyway. Transaction time — when you learned a fact, as distinct from when it was true — is not built either. Both are on the list, and neither is on this page pretending to exist.

From payment to endpoint,
without a download.

The whole product is a machine image. It already carries the runtime, the service unit and the first-boot hook, so nothing installs at launch and nothing can fail halfway through. Your instance is the same bytes we tested.

  1. At checkout

    One field

    You pay by card and give us a single thing: your twelve-digit AWS account ID. No forms, no discovery call, no procurement.

  2. Same day

    Shared account to account

    We share a private AMI directly with that account and sign your licence key by hand. No marketplace sits in the middle and nothing is ever downloaded.

  3. Ten minutes

    One stack

    Launch the CloudFormation template. Instance, separate data volume, elastic IP, automatic TLS, token in Parameter Store, nightly snapshots to your own bucket.

  4. Before you trust it

    Prove it yourself

    Run the included smoke test against your own endpoint. Sixteen checks covering auth, ontology, edge direction, ingest, stubs and write blocking. Non-zero exit on the first failure, so it drops straight into CI.

Sharing an image account-to-account is slower for us than a marketplace listing. It is also the reason we know exactly who is running the software, and the reason your security team gets a real answer when they ask.

Everything we would want to check
before spending anything.

You are being asked to run someone else’s software against your own data, on your own infrastructure, on the strength of a web page. Here is what makes that a reasonable thing to do.

It is your account

One instance, one EBS volume, your VPC, your region. No telemetry, no phone-home, no licence server: the software has no outbound dependency at all, so it runs quite happily in a subnet with no route to the internet. Access is controlled where it belongs — we share the machine image directly with your AWS account and nowhere else.

The engine is open

LadybugDB, MIT licensed, the maintained continuation of Kuzu, embedded in the API process. If we vanish tomorrow your graph is still a file on a volume you own, in a format with an open reader.

Nothing is behind the payment

The complete documentation is public — every endpoint, every status code, the operations runbook and the security model. Send it to your reviewer before you send us anything. It will answer them faster than we can.

We publish the limits

One writer at a time. One machine, no clustering — scale up, not out. Order, Group and Key need backticks. Deleting data is manual Cypher. All of it is written down under Limits and gotchas, so you find out now rather than in week three.

Thirty days

Full refund, no questions asked. It runs in your account, so there is nothing for us to switch off and nothing for you to migrate away from.

One licence.
No meter.

Not per seat. Not per query. Not per gigabyte, per node, per edge or per “credit”. We do not get paid more when you use it more, which is the only honest position from which to tell you to point everything at it.

A metered price would make us the wrong kind of partner: quietly hoping your ingest grows. A flat licence means the only way we grow is by being worth renewing, and the only way you grow is however you like.

£2,499

per instance · per year

Buy a licence Talk it through first

Checkout asks for your AWS account ID and nothing else. Thirty-day refund. Prefer an invoice, a longer term, or a proof of concept first? Email us and we will sort it out.

The image, and who can launch it

No dongle, no activation, no licence server to be down when you need it. Your right to run the software comes from the agreement you sign, and the image is shared privately with your AWS account rather than published. Nothing in the software checks up on you, and nothing stops working because an invoice arrived late.

The modelling session

Two hours on your ontology before you write it, with the person who wrote the parser. This is where the value is and it is where people get stuck, so it is in the price rather than on a rate card.

Updates and support

Every release for the term, and email that reaches a person who can read the stack trace. No tiers, no response-time table you have to buy your way up.

Not included

Your AWS bill, which is roughly $15 a month at the smallest useful size and is paid to Amazon, not to us. We would rather you saw that number separately.

The manual does two jobs.

Before you buy it is how you decide, which is why none of it is gated. After you buy it is how your team runs the system without waiting on us — the runbook, the backup story, the upgrade path and every status code the API can return.

Open the documentation Nothing behind a login

The questions a careful buyer asks first.

Where does our data actually live?

On an EBS volume attached to an instance in your own VPC, in the region you chose. We have no access to it and receive no telemetry from it. That is why the product is shaped this way rather than sold as a hosted service: in a regulated environment, “it never leaves your account” is the only answer that survives a security review without a six-week detour.

How locked in are we?

The query language is Cypher. The ontology is a JSON file you wrote and can read. The graph is a single file on a volume you own, written by an MIT-licensed engine. Snapshot it whenever you like. If you stop paying, the instance keeps running until you terminate it — the licence governs updates and support, not your ability to read your own data.

Is one machine really enough?

For most graphs, by a distance — and if it is not, we would rather you knew that now. Writes are serialised behind one lock because the engine is single-writer, so batching beats parallel ingest. There is no clustering: you scale up, not out. That is the honest trade for having nothing to operate, and it is a ceiling rather than a limit you will hit next month.

What happens when our model changes?

Additive changes apply cleanly: new objects, new properties, new edges. Changes that would contradict data already in the graph — retyping a property, changing a key, repointing an edge — return a 409 with the specific conflicts listed, and you resend with "force": true if you meant it. You find out before the data disagrees with the model.

How long until we see something real?

Launch the stack, PUT your ontology, POST a day of records. If the JSON is already shaped the way your systems emit it — and it usually is, because that is the entire design premise — you are walking paths the same afternoon. The slowest part is agreeing internally what the edges should be called, which is why the modelling session is included.

Does it call home, or check a licence?

No, and there is nothing for it to call. There is no licence server, no activation step and no telemetry — the instance has no outbound dependency, so it runs in an isolated subnet with no internet route at all. Your entitlement is the agreement you sign; the image is shared privately with your AWS account. We would rather be worth renewing than build something that can switch your production system off.

Can we build on top of it?

That is the intended shape. It is an HTTP API with a token, so dashboards, alerting, internal tools and agents all sit on the same instance. The ontology document also stores sections the graph itself ignores — KPIs, alerts, cohorts, attributions, app config — untouched, so every layer you build reads one source of truth instead of maintaining its own copy of what things mean. Two sections are refused outright: integration credentials and external database config, because both would be readable through /query and copied into every backup.

Who is actually behind this?

A small British studio, and early customers deal with the person who wrote the code. The instance you run is not managed by us and does not depend on us being awake. That is deliberate: the failure mode of a small vendor should never be your outage.

Ask the question you have been approximating.

A licence, a private image shared to your AWS account, and a stack that launches in about ten minutes. No third party in the middle, no data handed over, and a person on the other end of the email.

Buy a licence — £2,499/yr Talk it through first 30-day refund · AWS account ID at checkout