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 Posthog Laravel Package

qodenl/laravel-posthog

A Laravel package for integrating PostHog analytics into your app. Track events, identify users, and send data to PostHog through a simple, configurable API, making product analytics and feature flag workflows easier to add to Laravel projects.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. This package is a thin, opinionated Laravel service-provider wrapper around posthog/posthog-php, which is the right shape for a Laravel estate: config publishing, facade access (Posthog::), environment-driven configuration that survives config:cache, and queue-aware dispatch. Release 1.5.0 pushes it further from "analytics SDK wrapper" toward "observability surface" by adding error tracking and GeoIP-correct capture. That broadens the set of teams with a stake in the package (product analytics, growth/experimentation, and now platform/SRE for exception reporting), which changes the governance conversation: this is no longer a dependency only the growth team cares about.

Integration feasibility. Low effort on the happy path. Feature flag payloads (getFeatureFlagPayload()) read from the same cached evaluation as getFeatureFlag(), so there is no additional /flags request and no new network dependency — a genuinely cheap capability addition that unlocks remote config / JSON payload use cases that previously required a second vendor or a bespoke table. POSTHOG_RELEASE_ID working under config:cache and PHP-FPM without clear_env = no removes a real, commonly hit deployment footgun; teams that previously worked around it with a custom super-property or a deployed .env hack should retire those workarounds. Error tracking is opt-in via POSTHOG_ERROR_TRACKING_ENABLED, which is the correct default posture, but it hooks Laravel's exception handler and therefore touches a hot, failure-sensitive path.

Technical risk. Three items dominate.

  1. Laravel 11 removal is a hard break. Any application still on Laravel 11 cannot take this release at all; Composer will refuse to resolve. Laravel 11 is out of security support, so this is defensible, but it means the upgrade is gated on an application framework upgrade for lagging services. That is a programme-level dependency, not a package-level one.
  2. POSTHOG_CAPTURE_IP is a privacy and compliance change, not a technical toggle. Sending $ip on capture, identify, and captured exceptions means personal data now flows to PostHog from queue workers and web requests where it previously did not. Default false is correct, but the moment a team enables it, DPA/DPIA review, retention settings, and GeoIP region configuration all need to be confirmed. Note the nuance: IP is resolved from request()->ip() at dispatch time, so queued events carry the enqueuing request's IP — good for correctness, but it means IP data is persisted in the queue payload (database/Redis/SQS), which is a data-at-rest consideration some security reviewers will flag. resolveIpUsing() exists for proxies like Cloudflare and must be configured correctly or you will record edge/proxy IPs.
  3. Error tracking volume and PII. Reporting every exception that reaches Laravel's handler can be a large, spiky event volume (a single broken deploy, a crawler hitting a bad route, or a queue retry storm). Exception messages and stack traces frequently contain user identifiers, query fragments, or tokens. There is no mention of sampling, rate limiting, or scrubbing in these notes.

Key questions.

  • Which applications in the estate are on Laravel 11, and what is the cost/timeline to move them to 12? Is 1.4.x pinned for those, and for how long?
  • Is there a documented data-retention and PII position for $ip and for exception payloads? Has legal/security signed off?
  • Does error tracking have sampling or rate limiting, and what is the expected event volume multiple versus current capture traffic?
  • Does the package's exception hook interact correctly with existing reporting (Sentry, Flare, Bugsnag)? Double-reporting cost and alert noise?
  • What is the support window and release cadence for this package? Single maintainer?
  • Is the payload returned by getFeatureFlagPayload() safe to use as a remote-config trust boundary, or is it still gated behind getFeatureFlag() checks?

Integration Approach

Stack fit. Requires Laravel 12 or 13. PHP version floor follows the framework, so confirm the PHP baseline in CI matches what Laravel 12/13 require before planning. The package remains a single Composer dependency with one config file and a facade — no new infrastructure, no sidecar, no schema migrations. posthog-php ^4.14 is a minor bump within the existing constraint, so it should resolve without conflicting with other packages unless something else pins ^4.13 exactly.

Migration path. Treat this as two separate changes with two separate approvals:

  • Mandatory: framework uplift to Laravel 12 (or 13) in each consuming application, then bump the package. This is the gating step and should be tracked as ordinary framework-upgrade work, not package work.
  • Optional and independent: adopt getFeatureFlagPayload(), POSTHOG_RELEASE_ID, error tracking, and IP capture. Each is additive and off by default (except release ID, which is inert unless set). They can land in separate PRs after the upgrade and should not be bundled with it.

Applications that cannot move to Laravel 12 should pin to 1.4.x and accept that they stop receiving fixes — that needs an explicit owner and an end date, not a silent pin.

Compatibility. Two surfaces to verify. First, exception-handler behaviour: confirm the package's auto-capture coexists with whatever report()/render() customisations already exist, and that captureException() can be called manually (synchronously in a handler, or from a job) without blocking request teardown. Second, proxy/IP resolution: applications behind Cloudflare, ALBs, or any hop that rewrites REMOTE_ADDR must configure trusted proxies in Laravel and Posthog::resolveIpUsing() if they enable IP capture, or GeoIP will be systematically wrong. Also confirm queues are running a worker restart after config changes — config:cache semantics apply, so any POSTHOG_* change needs a deploy, not a .env edit.

Sequencing.

  1. Inventory applications by Laravel version; classify as "upgrade now," "upgrade this quarter," "pin to 1.4.x."
  2. Framework upgrade to Laravel 12/13, verified in staging with the package still on 1.4.x.
  3. Bump to 1.5.0 with all new features disabled. Soak. Confirm no change in event volume or handler behaviour.
  4. Enable POSTHOG_RELEASE_ID across the estate — lowest risk, highest immediate diagnostic value.
  5. Adopt getFeatureFlagPayload() in the one or two teams with a concrete remote-config use case; validate payload shapes and fallback behaviour for missing flags.
  6. Privacy review, then enable POSTHOG_CAPTURE_IP per application, starting with one behind a known proxy to prove resolveIpUsing().
  7. Enable error tracking last, starting at low-traffic scope, with volume monitored for the first week.

Operational Impact

Maintenance. Small surface area, but the package is version-coupled to Laravel releases: dropping Laravel 11 means a recurring annual-ish obligation to track framework support windows. Budget for that cadence rather than treating this as a one-off. The posthog-php transitive dependency will also drift; a Composer constraint bump is not something to leave unpinned for long.

Support. Error tracking means the platform/SRE team now owns a slice of this package's behaviour — specifically, whether exception reporting is complete, whether it double-reports alongside Sentry/Flare, and whether it stays within quota. That needs an owner. The $release_id super-property is a genuine support win: correlating error spikes and flag-call events to a deploy is the difference between a ten-minute and an hour-long incident triage. Conversely, if POSTHOG_RELEASE_ID is inconsistently set across services, dashboards become misleading, so it should be enforced the same way build metadata is.

Scaling. Three cost/volume axes shift:

  • Flag evaluation: getFeatureFlagPayload() reuses the cached evaluation, so no additional /flags traffic — neutral.
  • Event volume: error tracking is the material change. Unbounded exception capture under a retry storm can multiply event volume by a large factor in minutes. Confirm whether the package or PostHog's ingest applies sampling/rate limits before enabling broadly; if not, gate it per-environment (on in production, and consider explicitly off in high-churn batch workers).
  • Queue payload size: IP capture and enriched exception context increase queue message size modestly. Not a problem for Redis/database queues at typical volumes; worth a glance if you run very high-throughput SQS with a tight message-size ceiling.

Failure modes.

  • PostHog unavailable: capture should degrade to dropped events, not failed requests. Verify this explicitly, especially for captureException() inside the framework's exception handler — a throw during exception handling produces confusing secondary errors and can mask the original fault.
  • Missing feature flag: getFeatureFlagPayload() on an undefined flag or a flag disabled during rollout — teams must handle null/invalid payload and fall back to hardcoded defaults. Treat remote payloads as untrusted input and validate shape.
  • Misconfigured proxy: resolveIpUsing() unset behind Cloudflare silently attributes all traffic to edge IPs, corrupting GeoIP without erroring. Silent wrongness is the worst outcome here.
  • Unresolvable distinct ID on exception: the package falls back to anonymous send. Useful, but it means a fraction of error events will be unattributable — alerting rules must not assume a user is always present.
  • Laravel 11 estate: Composer resolution failure at deploy time — caught early, but only if CI runs against the same PHP/Laravel matrix as production.
  • Duplicate exception reporting: if Sentry/Flare remain in place, expect duplicated spend and two alert streams that disagree.

Ramp-up. Low for a Laravel developer: the facade, config file, and env vars are conventional, and captureException() plus getFeatureFlagPayload() are single-line calls that can be documented in the existing Laravel onboarding material. The real ramp-up cost is not developer skill — it is the cross-functional work of the privacy review for $ip and exception payloads, and the operational decision about whether PostHog error tracking supplements or replaces the incumbent error reporter. Resolve that question before enabling the flag, or you will run two overlapping systems indefinitely.

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.
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox