Service

Run MATLAB with Quix

Quix allows you to import the MATLAB engine and run a MATLAB process from within Quix, making it easier to leverage your data for calculations, modelling and simulations.

100% Python

No JVM, wrappers, DSL, or cross-language debugging. Quix provides a Python Streaming DataFrame API that treats data streams as continuously updating tables.

Rich stream processing features

Quix supports stateless and stateful operations, aggregations over hopping and tumbling windows, custom data processing functions, and exactly-once semantics.

Dependable at scale

Quix is scalable, highly available, and fault tolerant. It's optimized to process high-volume, high-velocity data streams with consistently low latencies.

This integration runs MATLAB functions inside real-time streaming pipelines on Quix. Data flows in from Kafka topics, MATLAB code processes it, and results are published back to Kafka — without rewriting models in another language. Two integration methods are provided: a compiled Wheel approach (recommended for production) and a direct MATLAB Engine approach (suited to development and iteration).

About the integration

The purple box in the diagram below is a Docker container running on Quix. Containers exchange data through Kafka topics which are represented by smaller boxes on either side of the MATLAB Runner container.

The template includes a working data source (generates 2D test vectors) and the MATLAB Runner. The downstream consumer is up to you. Any service that reads from a Kafka topic.

Which integration method to use

The right method depends on three things: whether you have a MATLAB licence server available at runtime, whether your functions depend on toolboxes that cannot be compiled, and how frequently you expect to change the MATLAB code once deployed.

Use the MATLAB Wheel if:

  • You do not have a licence server accessible from your deployment environment, or would prefer not to configure one
  • Your MATLAB functions compile successfully with the MATLAB Compiler (most standard functions and many toolbox functions do)
  • You want the smallest possible container image (~2-3 GB vs ~10+ GB)
  • You are deploying to production or CI/CD and need repeatable, self-contained builds

Use the MATLAB Engine if:

  • You depend on MATLAB toolboxes or features that the MATLAB Compiler does not support
  • You are actively developing and changing your .m files and want to avoid a recompilation step on every change
  • You already have a MATLAB licence server accessible from your deployment environment
  • You need the full MATLAB workspace, including interactive debugging or runtime evaluation

If you are unsure, start with the Wheel approach. It covers the majority of use cases and avoids the licence server dependency entirely. You can always switch to the Engine approach later if you hit a compilation limitation.

MATLAB Wheel

Compiles MATLAB functions into Python-compatible .whl packages using the MATLAB Compiler. At runtime, only the free MATLAB Runtime is required -- no licence server.

A provided utility, quix_compiler.m, handles the full compilation pipeline. Once compiled, the MATLAB function is called from Python as a native method:

import quixmatlab

quixmatlab_client = quixmatlab.initialize()
output = quixmatlab_client.rot(v, theta)

The compiled wheel ships with the container image, built on the matlab-runtime:r2024b base.

MATLAB Engine

Runs .m files directly using a MATLAB Engine instance inside the container. No compilation step. Edit the function, restart the container, and changes take effect immediately. Templates are provided for both MATLAB 2023b and 2025a.

A MATLAB licence server must be accessible at runtime (MLM_LICENSE_FILE environment variable), and the container image includes a full MATLAB installation.

import matlab.engine

eng = matlab.engine.start_matlab()
v = matlab.double([[x], [y]])
output = eng.MATLAB.rot(v, theta)

Key features

Direct MATLAB execution in streaming pipelines. Functions receive data from Kafka topics, process it, and publish results through the Quix Streams API. Serialisation, consumer groups, and topic routing are handled automatically.

No rewriting required. Both methods preserve the original .m files. The Wheel approach compiles them; the Engine approach runs them natively.

Automated compilation tooling. The quix_compiler.m utility takes any MATLAB function and produces a deployable Python wheel that handles the mcc invocation, setup.py generation, and wheel packaging in one step.

Standard Quix Streams architecture. The MATLAB processing step uses the same Application / StreamingDataFrame / sdf.update() pattern as any Quix transformation. It chains with Python processing, filters, aggregations, and multiple output topics.

Infrastructure-as-code deployment. Each variant (Wheel, Engine 2023b, Engine 2025a) is defined in quix.yaml with explicit resource allocations, topic bindings, and environment variables, tracked in Git alongside the MATLAB source.

Code sample

The complete Wheel-based processing service, consuming 2D vectors from Kafka and applying a MATLAB rotation function:

from quixstreams import Application
import numpy as np
import os
import quixmatlab

quixmatlab_client = quixmatlab.initialize()

def matlab_processing(row: dict):
    x = row["x"]
    y = row["y"]
    v = np.array([[x], [y]])
    theta = np.pi / 4

    output = quixmatlab_client.rot(v, theta)

    row["x_new"] = output[0][0]
    row["y_new"] = output[1][0]


def main():
    app = Application(
        consumer_group="CompilerSDKMatlab2024b_wheel_general",
        auto_create_topics=True,
        auto_offset_reset="earliest"
    )
    input_topic = app.topic(name=os.environ["input"])
    output_topic = app.topic(name=os.environ["output"])
    sdf = app.dataframe(topic=input_topic)

    sdf = sdf.update(matlab_processing)
    sdf.to_topic(output_topic)

    app.run()

if __name__ == "__main__":
    main()

The quixmatlab_client object exposes every function compiled into the wheel. To use a different MATLAB function, modify the matlab_processing callback. The build step for any new function is a single command:

quix_compiler('your_function', './output_folder')

This compiles the .m file, generates Python bindings, and builds the .whl package.

Scalability

Each MATLAB function can be deployed as an independent service with its own input and output topics. A thermal model, a structural analysis function, and a control algorithm can all run simultaneously in the same pipeline, sharing data through Kafka without interfering with each other. The MATLAB processing containers have defined CPU and memory allocations and can be replicated for higher throughput.

In production, the data source component can be replaced by any Kafka-connected source: test rig sensors, simulation orchestrators, or upstream normalisation services.

Use cases for this integration

  • R&D simulation pipelines
  • Real-time test data processing
  • MATLAB model operationalisation
  • Parameter sweep automation
  • Digital twin data integration

Main project components

2D Vector Data Source — Generates normalised 2D test vectors and publishes them to a Kafka topic at configurable intervals.

MATLAB Wheel Runner — Processes streaming data using compiled MATLAB functions. Runs on MATLAB Runtime without a licence server.

MATLAB Engine Runner (2023b / 2025a) — Processes streaming data using native MATLAB Engine. Runs .m files directly with full toolbox access. Requires licence server.

Technologies used

  • MATLAB — Numerical computing and model development
  • Quix Streams — Python streaming library for Kafka pipelines
  • Quix Cloud — Managed deployment platform
  • Apache Kafka — Event streaming for data transport
  • Docker — Containerisation for MATLAB Runtime and Engine deployments