First Steps
This walkthrough stays in-memory so you can learn the pipeline without running
external services. It defines a task, bootstraps StemApp, enqueues a
message, then verifies the result inside a single Dart process.
1. Define a task handler
Create a task handler (StemApp will register it for you):
class EmailTask extends TaskHandler<String> {
String get name => 'email.send';
TaskOptions get options => const TaskOptions(maxRetries: 2);
Future<String> call(TaskContext context, Map<String, Object?> args) async {
final to = args['to'] as String? ?? 'anonymous';
return 'sent to $to';
}
}
2. Bootstrap the in-memory runtime
Use StemApp to create the broker, backend, and worker in memory. The worker
lazy-starts on the first enqueue or wait call, so the common path does not need
an explicit await app.start():
final app = await StemApp.inMemory(
tasks: [EmailTask()],
workerConfig: const StemWorkerConfig(
queue: 'default',
consumerName: 'first-steps-worker',
),
);
3. Enqueue from a producer
Enqueue a task from the same process:
final taskId = await app.enqueue(
'email.send',
args: {'to': 'hello@example.com'},
);
print('Enqueued $taskId');
4. Fetch task results
Result backends store the task state and payload:
final result = await app.waitForTask<String>(taskId);
print('Task state: ${result?.status.state} value=${result?.value}');
Choose a broker and backend
Stem lets you mix brokers and backends. Use this quick guide when selecting your first deployment:
| Need | Broker | Backend |
|---|---|---|
| Lowest latency, simplest ops | Redis Streams | Redis or Postgres |
| SQL visibility & durability | Postgres broker | Postgres |
| Local dev & tests | In-memory | In-memory |
Decision shortcuts:
- Start with Redis unless your org mandates another transport.
- Use Postgres when you want a single durable store or SQL-level visibility.
- Use in-memory only for local tests/demos.
For more detail, see Broker Overview and Persistence.
When you move past the in-memory demo
- Install Stem and the CLI as shown in Quick Start.
- Ensure
stem --versionruns in your shell.
Reuse the same task definitions
- Register tasks and options via
StemAppor a shared task list (see Tasks & Retries). - Wire producers with the same task list (see Producer API).
Split producers and workers into separate processes
- Once you leave the in-memory app, start workers against your broker and queues (see Connect to Infrastructure).
- Use Worker Control CLI to confirm it is responding.
Enqueue from apps or the CLI
- Enqueue from your app or the CLI (see Producer API).
Add a durable result backend
- Configure a result backend for stored task results and groups (see Persistence).
Add environment-based configuration
- Use
STEM_*environment variables for brokers, routing, scheduling, and signing (see CLI & Control). - Define routing rules in
STEM_ROUTING_CONFIGfor multi-queue setups (see Routing).
Troubleshooting
- Diagnose common errors in Troubleshooting.
Next steps
- Move to Connect to Infrastructure to wire routing, autoscaling, and multi-queue workers.
- Review Broker Overview for transport tradeoffs.
- Explore Persistence to store results in Redis or Postgres.