> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mixpeek.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Running inside your existing Ray cluster

> Why Mixpeek brings its own Ray, and what a shared-cluster deployment would cost

<Warning>
  This is not part of Customer-Hosted Mixpeek v1. Mixpeek deploys its own
  `RayService` into your namespace, running our Ray, our image and our CUDA
  userspace. Running Mixpeek workloads inside a `RayCluster` you already operate is
  a separate enterprise integration, scoped and priced per deployment.

  This page explains what we measured when we scoped it, so the decision is
  inspectable instead of a policy you have to accept.
</Warning>

## What the shared-cluster contract would cost

A Ray cluster runs one image. When we bring the cluster the image is ours, so
your Ray, Python and CUDA versions are not inputs to anything. When the cluster is
yours, our workloads run in your runtime, and three things follow.

**Mixpeek would have to publish an engine image built against your Ray version.**
Your version becomes part of our build matrix and stays there, so a Ray upgrade on
your side turns into a Mixpeek compatibility event on ours. That fails the test we
hold the product to: can Mixpeek upgrade itself without asking your platform team
to upgrade a dependency first?

**Your CUDA and Python userspace become ours to match.** Model code that we
qualify once against our own pinned userspace would need qualifying against
each customer's.

**Serve lifecycle becomes shared.** The detail below is the one we would most
want a customer to read before asking for this.

## The Serve lifecycle hazard, measured

Ray Serve's configuration API is declarative over the whole application set. A
config that does not name an application removes it. Whether that reaches your
applications depends on whether Serve is holding a config for them.

| How your app was deployed                      | Serve holds its config | A whole-config deploy |
| ---------------------------------------------- | ---------------------- | --------------------- |
| `serve.run(...)` in Python, imperative         | No                     | **Leaves it alone**   |
| A config `PUT` or `serveConfigV2`, declarative | Yes                    | **Removes it**        |

You can check which you have. An application with an empty `deployed_app_config`
in `GET /api/serve/applications/` was deployed imperatively and sits outside the
lifecycle that config governs.

<Note>
  Measured on Ray 2.53.0 with KubeRay 1.5.1, on a single-head cluster with one
  application of each kind: the same whole-config deploy removed the declaratively
  deployed application and left the imperative one with a byte-identical deploy
  timestamp. That is enough to state the asymmetry. It is not a promise that a
  whole-config deploy is safe on your cluster, and we do not make one.
</Note>

Mixpeek's deploy path never uses the whole-config route on a cluster it does not
own. We add, scale and remove one named application at a time, which cannot reach
another application however yours were deployed. That mitigation works, and it
exists because the hazard is real. Owning the `RayService` removes the hazard
rather than mitigating it, which is the cleaner answer and the one v1 ships.

Route prefixes carry a smaller version of the same problem. Serve routes on
longest matching prefix, so `/` and `/forecast` coexist. Our deploy path refuses a
prefix that would collide with one of yours, and refuses to take `/` on a shared
cluster unless explicitly told to, because every request your applications do not
match, including their 404s, would start arriving at ours.

## If you need this anyway

Some deployments have a hard requirement to use an existing cluster. Tell us your
Ray, Python and CUDA versions first, because those decide whether the integration
is feasible before anything else is worth discussing.

The qualification suite already carries the rows this contract needs, and they
run today on our fixtures:

* `serve-lifecycle` deploys, scales and removes one named Mixpeek application and
  asserts your application kept its status, replica count and **deploy
  timestamp**. The timestamp is the sharp signal, because a reconcile that took
  your app down and put it back leaves the first two unchanged.
* `non-interference` snapshots every foreign application, job and actor before and
  after.
* Both are preceded by a quiet-window control. The suite watches your cluster with
  nothing of its own in flight, and if anything moves on its own it reports
  INCONCLUSIVE rather than attributing the movement to Mixpeek.

<Warning>
  If your cluster is under memory pressure or still settling, the isolation rows
  report INCONCLUSIVE rather than a verdict. That is deliberate. A foreign
  application restarting because the cluster is struggling looks identical to one
  disturbed by us, and reporting the second when the first is true would be a
  finding about your cluster that we invented.
</Warning>
