Why we started with PostHog at Autoplay
How we turned PostHog from an analytics tool into the event backbone for real-time agents.
We just launched the Autoplay SDK.
That makes this a useful moment to explain a design choice that sits underneath it: why our real-time architecture started with PostHog.
Autoplay is not a reporting layer. It is infrastructure for turning live product behavior into model-readable context. The SDK is the public interface to that system. You connect your app, stream real-time user activity into your service, and receive typed payloads that can be embedded, stored, retrieved, and passed into agents or copilots. In our docs, that flow is explicit: browser activity enters the Autoplay connector pipeline, gets extracted, normalized, and optionally summarized, then arrives over SSE or push webhook as typed payloads your application can use directly.
That architecture needs a specific kind of event layer.
It needs broad browser-side capture with low frontend burden. It needs identity and session continuity. It needs an event model that is simple enough to ingest at scale but expressive enough to carry useful context. It needs a clean way to route that stream into your own infrastructure in real time. It needs enough structure that downstream systems can reason over it programmatically. And it needs pricing that makes dense behavioral capture practical, not something you immediately start trimming.
Those are the reasons we started with PostHog.
That phrasing matters. We do plan to support other analytics layers over time. But when we were building the first version of this architecture, PostHog was the cleanest fit for the problem in front of us. It gave us the best starting point for building a real-time behavioral backbone that could power agents, copilots, memory systems, and retrieval pipelines, not just dashboards.
The architecture we actually run
In our standard setup, a customer installs posthog-js in the frontend, initializes it with their Autoplay API key, attaches a product_id, and identifies the user again after login with their application user ID and optionally email. That gives us the behavioral stream, the routing key, and the identity bridge we need for session and conversation linking. Our quickstart also uses a two-minute session idle timeout so the stream stays aligned with how we package live context downstream.
From there, we configure a PostHog webhook destination pointed at the customer’s Autoplay connector. That is the important boundary in the system. Before that point, you have events. After that point, you have context.
Autoplay takes the incoming stream and turns it into something agent systems can actually use. We extract raw browser activity into normalized actions, label those actions in natural language, group them into sessions, and optionally summarize the session into compact prose. The SDK then exposes that as typed ActionsPayload and SummaryPayload objects over SSE or push webhook. Those payloads are designed to flow straight into vector stores, memory systems, copilots, and RAG pipelines.
The path looks like this:
posthog-js captures browser activity.
PostHog ingests the events and attaches user and session context.
PostHog forwards selected events to the Autoplay connector.
Autoplay extracts, normalizes, labels, groups, and optionally summarizes the session.
autoplay-sdk consumes the resulting stream over SSE or push webhook.
Your service embeds that context, writes it to memory or retrieval infrastructure, and passes it into a model.
The model decides whether to stay silent, answer reactively, or trigger proactively.
That is the architecture we use ourselves. But the more useful point is that it is also a pattern other teams can adopt. If you want support systems that know what the user was doing before they opened chat, copilots that react to real workflow state, or memory systems that update from product behavior instead of only from text conversations, this is the kind of event backbone you need.
Why the event model mattered
The core unit in PostHog is an event: a user or distinct_id, a timestamp, an event name, and a JSON-like property blob. Those properties can include text, booleans, numbers, dates and timestamps, arrays, and nested objects. That sounds basic, but it is exactly what made the model useful outside dashboards. It is flexible enough to carry product-specific context, and typed enough to stay understandable as the system grows.
That flexibility also matters operationally. Teams can define event schemas, manage event definitions, and group properties so structure stays consistent and discoverable over time rather than drifting into a mess of ad hoc payloads. Events can also be enriched with user properties, group properties, and custom metadata, which matters because downstream analysis is rarely based on a naked click stream. Useful systems usually need organization-level context, user state, workflow identifiers, route keys, and product metadata attached to the underlying behavior.
That is what made PostHog a strong starting point for us.
If you are building agent systems, the raw requirement is not “have events.” It is “have events that can be turned into state.” You need enough flexibility to attach product IDs, route keys, workflow hints, or metadata without fighting the schema. You need enough structure that your application can reason over the stream programmatically. And you need enough consistency that models are not being fed an ever-changing mess of telemetry. PostHog gave us a strong base layer for that, and then Autoplay does the second half of the work by turning that event stream into typed actions and readable session summaries.
Why capture quality mattered
If you are trying to build on top of behavior, instrumentation burden matters as much as event quality.
PostHog’s web SDK automatically captures pageviews, pageleaves, clicks, input changes, and form submissions for common interactive elements by default. That meant teams could get broad behavioral coverage quickly rather than spending weeks manually instrumenting every workflow before they could test anything useful. For our use case, that mattered because the captured stream is not the final product. It is the substrate we transform into agent context. The faster you can get a high-coverage stream, the faster you can start turning real behavior into something your models can use.
This is one of the biggest reasons it made sense as our starting point. A product team, support engineering team, or platform team can start with the same behavioral stream they already want for analytics, then use that same stream to power runtime systems. That means fewer duplicate SDKs, fewer competing schemas, and less drift between what the dashboard says happened and what the copilot thinks happened.
Why routing mattered
A lot of analytics products are good at collecting events and surfacing them in charts. That is not the same as being comfortable in the middle of a live product system.
For our use case, the event layer had to be adjacent to runtime. It had to let events move outward in real time into our own pipeline, not stop inside a reporting product. PostHog’s platform explicitly distinguishes between public capture endpoints and private query endpoints, and supports real-time destinations and webhooks in its broader product surface. It also supports transformation and enrichment patterns at ingestion time, which helps keep downstream data clean and structured before it reaches the systems that actually consume it.
Its public POST-only endpoints, including event capture at /i/v0/e, are not rate-limited, while private authenticated endpoints are rate-limited separately. For many analytics endpoints, the documented limits are about 240 requests per minute and 1,200 per hour. The query endpoint allows up to 2,400 per hour. Other private read and write APIs are capped around 480 per minute and 4,800 per hour per API key.
That separation is exactly what you want when the critical path is capture and forwarding, not dashboard queries.
In other words, if you are building agents, copilots, or internal systems that need the behavioral stream while the session is still alive, the shape of the API matters. You do not want the useful path to depend on a reporting endpoint. You want ingestion to feel like infrastructure. PostHog was a strong fit for that, which is why we started there.
I am also deliberately being precise here on latency. We treat the stream as effectively live in practice, which is what matters for our architecture. I am not making a hard benchmark claim here about exact milliseconds, and I am not claiming exact queue behavior for other vendors without controlled benchmarks. The important point is architectural: PostHog was designed in a way that made real-time capture and routing practical for our first version.
Why sessions and replay mattered
Single events are useful. Real user workflows are sequences.
PostHog supports both event capture and session replay. That mattered because teams often need both views at once: the granular stream for live state, and the session-level view for validating friction, detours, hesitation, and workflow breakdowns.
Session recordings are a separate unit from standard analytics events. They are stored and priced per session or recording, not per event. They are also more expensive per item than standard analytics events, which makes sense because they are a denser resource. PostHog’s pricing treats session replay as a separate resource, with a free tier and then tiered per-recording pricing beyond that. Product analytics events are priced separately, starting at roughly $0.00005 per event after the first 1 million monthly events, which are free.
Architecturally, that distinction is useful.
The high-volume event stream is what powers real-time state and downstream decisions. Session replay is the denser, slower path you use to inspect complete workflows, validate behavior, and build better models of how users actually move through the product. It helps you see detours, friction points, hesitation, and navigation patterns that matter when you are trying to understand real workflows instead of isolated clicks. If you care about product-aware AI, having both event-level and session-level data available in one stack is a real advantage.
Why pricing was part of the technical decision
Pricing is not a procurement detail here. It shapes what you can build.
If your event layer is too expensive, teams start deleting the very signal that makes behavioral systems useful. PostHog’s usage-based pricing keeps the basic model simple: the first 1 million product analytics events per month are free, then pricing starts at $0.00005 per event and decreases with scale. That is about $50 per 1 million events at the starting paid tier. Session replay has its own free tier and tiered pricing by recording, and those recordings are priced separately because they are a different resource than standard analytics events.
That mattered for us, but it also matters for anyone experimenting with real-time support or product-aware copilots. You need enough behavioral density to make the model useful. If every additional event feels like a billing risk, the system gets blind very quickly.
It also means startups and early-stage teams can get a meaningful amount of signal before the event layer becomes a real cost center. If you are capturing tens or even hundreds of thousands of events per month, you are still working in a pricing model that feels like infrastructure, not something that forces aggressive under-instrumentation on day one.
Where the SDK fits in
This is also why we launched the SDK in the shape we did.
autoplay-sdk is not another analytics SDK. It is the interface to the transformed stream. It consumes the connector over SSE or push webhook and hands your application typed Python objects, not raw JSON blobs. ActionsPayload gives you session ID, user ID, product ID, ordered actions, counts, and an embedding-ready .to_text() method. SummaryPayload gives you a prose version of the session when you want compact context instead of a full action list. The SDK also supports async and sync clients, push and pull delivery, Redis-backed buffering, and per-session concurrency isolation, so a slow downstream job in one session does not block another.
A simple frontend setup looks like this:
import posthog from ‘posthog-js’
posthog.init(’YOUR_AUTOPLAY_API_KEY’, {
api_host: ‘https://us.i.posthog.com’,
person_profiles: ‘identified_only’,
session_idle_timeout_seconds: 120,
loaded: (posthog) => {
posthog.identify(posthog.get_distinct_id(), {
product_id: ‘YOUR_AUTOPLAY_PRODUCT_ID’,
});
},
})
// after login
posthog.identify(user.id, {
product_id: ‘YOUR_AUTOPLAY_PRODUCT_ID’,
email: user.email,
})And then the downstream service consumes the live stream:
import asyncio
from autoplay_sdk import AsyncConnectorClient
STREAM_URL = “https://your-connector.onrender.com/stream/YOUR_PRODUCT_ID”
API_TOKEN = “unkey_xxxx...”
async def on_actions(payload):
text = payload.to_text()
embedding = await embed_api.create(input=text)
await vector_store.upsert(id=payload.session_id, vector=embedding)
async def on_summary(payload):
text = payload.to_text()
await vector_store.upsert(id=payload.session_id, vector=await embed(text))
async def main():
async with AsyncConnectorClient(url=STREAM_URL, token=API_TOKEN) as client:
client.on_actions(on_actions)
client.on_summary(on_summary)
await client.run()
asyncio.run(main())The point is not just that this works. It is that customers do not need to build the interpretation layer themselves. PostHog captures the live behavioral stream. Autoplay turns it into typed, LLM-ready context. The SDK makes that context easy to consume.
That is useful whether you are building with Autoplay specifically or thinking about the general pattern. The better the event backbone is, the less custom interpretation code you need to write yourself.
What this enables in practice
This is not just good for us. It is useful for a lot of teams working close to product behavior.
A support team can build a copilot that already knows what the user was doing before they opened chat.
A product team can build a proactive assistant that notices repeated no-progress behavior and intervenes at the right moment.
A growth or onboarding team can track whether someone has actually completed a workflow, not just visited a page.
An engineering team can update user memory or retrieval systems from real behavior instead of only from text inputs.
These are the kinds of use cases our docs are built around: real-time events first, then memory, then golden paths, then trigger logic that decides when to proactively help and when to stay quiet.
The key point is that they can all share the same behavioral stream.
That is the real architectural benefit. You do not need one telemetry layer for analytics and a second completely separate telemetry layer for runtime AI. PostHog gives you the capture, identity, sessioning, and event backbone. Autoplay turns that stream into typed, model-readable context. The SDK exposes it in a form developers can use directly.
The real reason we started with PostHog
The shortest version is this:
We did not need a tool that was only good at telling us what happened last week.
We needed a tool that could sit in the loop between user behavior and system response.
That meant the event layer had to capture enough detail without heavy manual instrumentation, preserve identity and session continuity, support a flexible but typed data model, allow enrichment with user, group, and product context, route data outward in real time, remain open to programmatic consumption, support both events and sessions, and stay affordable enough to use as infrastructure.
PostHog had that combination.
That does not mean it is the only analytics layer we will ever support. It means it was the right place to start.
At Autoplay, that is what let us take a live behavioral stream, turn it into typed LLM-ready context, and use it to power agents and copilots in the moment. But the more general point is this: if you want product data to do more than describe the past, you need an event backbone that is comfortable powering systems outside the dashboard too.
That is why we started with PostHog. And that is why the setup is useful for our customers as well.

