Define distributed processes in code, and let LittleHorse orchestrate, track, and govern them.
LittleHorse is a high-throughput, low-latency microservice orchestration engine that allows developers to build scalable, maintainable, and observable applications. LittleHorse's Business-as-Code approach allows you to write code that closely mirrors your business processes, creating better alignment between product & engineering while providing a robust durable execution platform.
Let LittleHorse take the reins and ditch the headaches of:
- Wiring microservices together with RPC calls or message queues.
- Managing the coordination and sequencing of your applications.
- Retries, timeouts, dead-letter queues.
- Distributed tracing and debugging across multiple microservices.
- Scheduling actions to asychronously happen in the future.
- Backpressure and scalability.
LittleHorse is built on Apache Kafka and Kafka Streams, and has rich integrations with the Kafka Ecosystem.
☝️ This picture shows a running instance (WfRun) for the process (WfSpec) defined by this code 👇
public void quickstartWf(WorkflowThread wf) {
WfRunVariable fullName = wf.declareStr("full-name").searchable().required();
WfRunVariable email = wf.declareStr("email").searchable().required();
// Social Security Numbers are sensitive, so we mask the variable with `.masked()`.
WfRunVariable ssn = wf.declareInt("ssn").masked().required();
WfRunVariable identityVerified = wf.declareBool("identity-verified").searchable();
wf.execute(VERIFY_IDENTITY_TASK, fullName, email, ssn).withRetries(3);
NodeOutput identityVerificationResult = wf.waitForEvent(IDENTITY_VERIFIED_EVENT)
.timeout(60 * 5) // 5 minute timeout
.withCorrelationId(email)
.registeredAs(Boolean.class);
wf.handleError(identityVerificationResult, LHErrorType.TIMEOUT, handler -> {
handler.execute(NOTIFY_CUSTOMER_NOT_VERIFIED_TASK, fullName, email);
handler.fail("customer-not-verified", "Unable to verify customer identity in time.");
});
identityVerified.assign(identityVerificationResult);
wf.doIf(identityVerified.isEqualTo(true), ifBody -> {
ifBody.execute(NOTIFY_CUSTOMER_VERIFIED_TASK, fullName, email);
})
.doElse(elseBody -> {
elseBody.execute(NOTIFY_CUSTOMER_NOT_VERIFIED_TASK, fullName, email);
});
}As you can see, the code above closely mirrors our example KYC business process. LittleHorse handles retries, timeouts, and orchestration across services for you, allowing your WfSpec to focus just on what matters to the business. Task workers handle integrations with external systems and databases.
Run your first WfRun in 120 seconds or less.
Run the LittleHorse Server and Dashboard using our standalone docker image:
docker run --rm --pull=always --name littlehorse -d -p 9092:9092 -p 2023:2023 -p 8080:8080 ghcr.io/littlehorse-enterprises/littlehorse/lh-standalone:latest
Note: if you want to play with the output topic, which sends workflow updates to Kafka in real time, this also exposes a Kafka broker on
localhost:9092.
brew install littlehorse-enterprises/lh/lhctlAlternatively, you can install it from our GitHub Releases page
Once you have lhctl ready, let's use the whoami command to verify that the LittleHorse Server is up and running:
lhctl whoami{
"id": {
"id": "anonymous"
},
"createdAt": "2026-03-05T02:51:57.229Z",
"perTenantAcls": {},
"globalAcls": {
"acls": [
{
"resources": [
"ACL_ALL_RESOURCES"
],
"allowedActions": [
"ALL_ACTIONS"
],
"name": ""
}
]
}
}Start an example in a language of your choice. This will do three things:
- Register a
TaskDef(Task Definition) in the LittleHorse Server. - Start a Task Worker which polls the LittleHorse Server, waiting to be told to execute a
TaskRun. - Register a
WfSpec(Workflow Specification) which simply invokes a the above task worker.
The WfSpec has a single input variable (input-name), and that name is passed into the greet task worker.
./gradlew example-basic:run
cd examples/python/basic
poetry shell
python -m example_basic
In one terminal, start the task worker (leave it running):
go run ./examples/go/basic/worker
Then in another terminal, register the WfSpec:
go run ./examples/go/basic/deploy
cd examples/dotnet/BasicExample
dotnet runFirst, install dependencies and register the WfSpec:
cd examples/js/simple-worker
npm install
npm startThen in another terminal, register the WfSpec (note that our JS sdk does not yet support creation of WfSpecs, so we use lhctl here)
cd examples/js/simple-worker
lhctl deploy wfSpec example-basic-wfspec.jsonNow let's run your first WfRun with lhctl, setting the value of the input-name variable to "Obi-Wan":
lhctl run example-basic input-name Obi-WanNow, navigate to the dashboard at http://localhost:8080 and inspect your first WfRun!
You can also use lhctl to investigate! For starters:
lhctl get wfRun <wfRunId>lhctl get nodeRun <wfRunId> 0 1lhctl list taskRun <wfRunId>
- Check out our Concepts Documentation!
- Run more examples in our examples directory.
- Join our Slack Community
To run a workflow with LittleHorse, you need to:
- Define tasks which are units of work that can be used in a process, and implement programs that execute those tasks.
- Define your workflows and tell the workflow engine about it
- Run the workflow
- The workflow engine ensures that your process gets executed correctly.
To get started quickly with a basic workflow, try our quickstarts in Java, Go, Python, and C#. For more detailed examples, you can check out:
- The examples directory in this repo
- The lh-examples repository, which contains more complex applications.
For documentation, visit littlehorse.io/docs/server.
LittleHorse is developed with love by engineers, for engineers.
The LittleHorse Server follows Semantic Versioning after the release of version 1.0. You can find our (non-binding) project guidelines regarding our release schedule and deprecation strategy in our project lifecycle document.
For information about developing LittleHorse, see the guide in our local-dev README.
All code in the ./server and ./dashboard directories in this repository is licensed by the GNU Affero General Public License, Version 3 and is copyright of LittleHorse Enterprises LLC.
All docker images from this repository are licensed by the GNU Affero General Public License, Version 3 and are copyright of LittleHorse Enterprises LLC.
All other code and packages, including our SDK's, lhctl, examples, and the corresponding packages is licensed by the Apache License 2.0.

