Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Temporal Laravel Package

keepsuit/laravel-temporal

Laravel Temporal integrates the Temporal PHP SDK with Laravel, making it easy to define and register workflows and activities, configure task queues and workers, and run durable background workflows using familiar Laravel configuration and Artisan commands.

View on GitHub
Deep Wiki
Context7

Getting Started

  • composer require keepsuit/laravel-temporal — the service provider and facade are auto-discovered. You also need a reachable Temporal server; for local work run the Temporal CLI dev server (temporal server start-dev) rather than standing up a cluster.
  • Publish and read the config first: php artisan vendor:publish --tag=temporal-config → config/temporal.php. The knobs that matter on day one are address (usually from TEMPORAL_ADDRESS, default 127.0.0.1:7233), namespace, the default task queue, and the TLS/mTLS block for Temporal Cloud.
  • Look at three things next, in this order: the TemporalWorkflow / TemporalActivity contracts (they define the shape of everything you'll write), the Temporal facade / workflow-client surface (how you start work), and TemporalFaker (how you'll iterate 90% of the time).
  • A good first vertical slice is an order/onboarding workflow: one workflow class with an execute() method that calls two activities — one that hits an external API via your existing HTTP client, one that sends a notification. Start it from a controller with Temporal::newWorkflow(OrderWorkflow::class, $orderId)->start(), and run a worker to execute it. That exercises the full loop: dispatch → queue → activity container resolution → result.
  • Treat the worker as infrastructure from hour one, not an afterthought. Whatever artisan command the package exposes for workers, run it under Supervisor/systemd in a separate process from your web app — the worker is what actually executes your workflow and activity code.

Implementation Patterns

  • Workflows are orchestration, activities are the work. Keep execute() free of I/O: it should only sequence activity calls, timers, child workflows, and signal/query handling. Every DB query, HTTP call, mail send, and file operation belongs in an activity class.
  • Dependency injection is asymmetric. Activities are resolved through the Laravel container, so they can take your repositories, services, and HTTP clients in the constructor. Workflow classes get resolved too, but anything injected into them must be serializable and deterministic — inject workflow/activity stubs and plain values, not Eloquent connections.
  • Use explicit workflow IDs for idempotency. ->workflowId("order-{$orderId}") makes a retried dispatch (queue redelivery, user double-click, webhook replay) collapse into the existing run instead of spawning a duplicate. Combine with ->workflowExecutionTimeout() / ->taskQueue() as needed.
  • Signals and queries for long-running flows. Human-in-the-loop approvals, cancellations, and "current status" reads map cleanly onto signals (mutate workflow state) and queries (read it). Keep the state on the workflow class as properties and expose it via query methods rather than persisting intermediate state to MySQL.
  • Child workflows for composition. Split large sagas into a parent that fans out to children — it keeps each workflow's history small and makes retries scoped to the failing segment.
  • Testing loop: Temporal::fake() in feature tests, assert assertWorkflowStarted, and unit-test activities directly with normal Laravel test doubles since they're plain container-resolved classes. Reserve running against the real dev server + a worker for a small set of integration tests, because that's slow.
  • Local development: give each developer their own task queue (or their own namespace) and start the worker against it. Otherwise one dev's worker picks up another dev's workflow executions and you get baffling "my code changes do nothing" behaviour.
  • Deployment: ship workers alongside the app on the same release, and never mutate the shape of a running workflow (activity order, class names, argument types) — add a new versioned workflow class or use the SDK's versioning/patching helper for anything already in flight.

Gotchas and Tips

  • Upgrade to 2.3.2 if you don't use spatie/laravel-data. In 2.3.1 and earlier, workflow execution crashes when the Spatie data package isn't installed, because the data-converter path assumes it. If you do use Spatie DTOs, the fix is a no-op — but keep the version constraint loose enough that you don't get stuck on a broken 2.3.1 pin in a lock file.
  • Determinism failures are the #1 support ticket. No now(), Carbon::now(), rand(), env(), config(), Str::uuid(), or Model::find() inside a workflow — replay re-executes the method and any non-deterministic value desyncs history. Use the SDK's workflow clock (Workflow::now()) and move everything else into activities.
  • Never pass Eloquent models or closures as workflow/activity arguments. Pass IDs, scalars, or DTOs. If you use spatie/laravel-data, remember that the worker must be able to deserialize the same class — deploying a changed DTO while old runs are queued will blow up on hydration.
  • "Workflow started but nothing happened" is almost always a task-queue mismatch between the dispatcher and a running worker, or a worker that isn't running at all. Check the Temporal UI's workflow detail page — it shows pending tasks and the queue name — before touching your code.
  • Changing workflow code doesn't affect in-flight runs the way you expect. Workers cache workflow definitions at boot and replay history against current code, so editing a running workflow produces non-determinism errors rather than picking up the new logic. Restart workers after deploys, and version rather than edit.
  • Config caching bites. php artisan config:cache in deploy means TEMPORAL_ADDRESS changes require a re-cache; a worker pointing at localhost in production fails with a connection error that looks like a code bug.
  • Long activities need heartbeats and explicit timeouts, otherwise a slow third-party API turns into silent retries that duplicate side effects. Make activities idempotent by key (order ID, idempotency header) and set startToCloseTimeout deliberately rather than relying on defaults.
  • Extension points worth knowing: a custom data converter (for your own payload serialization), middleware/interceptors for cross-cutting concerns like tracing and auth propagation, and the package's attributes for declaring workflow/activity options inline instead of in config arrays. If you find yourself writing the same ->taskQueue(...) or timeout chain on every dispatch, that's the signal to build a small factory/helper around the facade.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle