A 500-microsecond parse cost is negligible in a quarterly report, but it compounds when an agent makes 200 decisions per minute. Between session.query() and returned data, LaserData passes through five distinct stages. Knowing what each stage does tells you where to look when a query is slower than expected.
This post follows a standard context-fetch query end to end. More complex multi-step queries use the same stages, with extra work during planning and optimization.
Stage 1: Parse
Parsing turns the query into a structured abstract syntax tree (AST). LaserData's compact query language resembles JSON and uses a small operator set. Because agents issue queries in tight loops, the parser minimizes overhead. An added 500 microseconds means little for a quarterly report, but compounds for an agent making 200 decisions per minute.
The parser also recognizes query templates. When an agent repeats the same query shape with different parameters, as context fetches commonly do, LaserData identifies the shape, retrieves its existing AST, and inserts the new parameters. Structural parsing happens only once. The first execution pays the full parse cost; later executions pay only parameter substitution, which is approximately an order of magnitude cheaper.
This resembles prepared statement optimization in traditional databases, but works at the template level without explicit client-side preparation. The agent does not declare a prepared statement. The execution engine infers one from repeated structural similarity.
Stage 2: Validate and bind
Once parsed, the query is checked against the session's schema context. Validation verifies that referenced fields exist, filter predicates use compatible types, and the query stays within the session's authorized data scope.
Binding maps logical field names to physical storage addresses. LaserData stores field names separately from field values, so repeating that lookup during execution would add needless cost. Binding replaces AST field references with direct offsets in the physical record layout. Field access then reads the precomputed offset instead of resolving a name at runtime.
Binding resolves session context variables as well. A query may use the current session identifier, current agent step number, or other session metadata in a filter. The bind phase turns those references into concrete values, allowing execution to treat them as constants rather than runtime lookups.
Stage 3: Plan
Using the bound AST, the planner builds a logical execution plan, the operation sequence of scans, filters, projections, and joins needed for the result. A primary-key lookup for one record has a short plan. Fetching context records that match a predicate and enriching them with related data from another record type requires several operations.
Join ordering is the central planning choice for agent queries. Context access often resembles a relational join: fetch the agent's current session record, then fetch each referenced knowledge base entry in full. A naive nested loop performs a lookup per entry. LaserData instead detects the pattern and creates a batched plan: collect the entry identifiers, read them in one batch, then assemble the result.
This directly addresses the N+1 read problem in agent workloads. When an agent step references eight prior context entries, it performs one batch read of eight records instead of eight serial reads. Fewer round-trips are the main reason well-planned queries have different latency from poorly planned ones.
Stage 4: Optimize
The optimizer rewrites the logical plan to lower execution cost. For agent queries, the key passes are predicate pushdown, access path selection, and projection pruning.
Predicate pushdown applies filters as early as possible. For a query that fetches recent context and filters on a timestamp, the optimizer moves that condition to the storage scan instead of waiting until records enter working memory. Records failing the filter are never materialized.
Access path selection chooses an index, range scan, or full scan for locating records. LaserData indexes session identifier for session-scoped reads and timestamp for recency-ordered queries, the dominant agent memory access pattern. A query filtering by session ID and limiting by recency uses both indexes and typically reads very few physical records.
Projection pruning removes fields absent from the query output. If an agent needs only context content and timestamp, it does not need the complete record or its metadata fields. The projector drops those fields early, reducing data passed to later stages.
Stage 5: Execute
The executor runs the optimized plan against physical storage. LaserData uses vectorized evaluation: instead of taking each record through the entire pipeline, it moves batches through each stage in sequence.
Vectorized execution improves CPU cache use. When a filter runs over 64 records, its evaluation loop processes 64 consecutive in-memory values. The CPU prefetcher can predict that pattern and load the next batch before the current one finishes. Single-record evaluation lacks a regular enough access pattern for equally effective prediction.
Agent queries commonly return small sets, typically 1-20 records, so the batch often contains the entire result. The vectorized pipeline runs once, returns the data, and exits. Paging overhead is absent in the common case.
Result delivery and streaming
After execution, results are serialized and sent over the session connection. Standard fetches return the complete result in one response. With stream: true, records are delivered individually as they come from the execution pipeline. The agent can start reading before the full result set is complete, which matters when the set is large.
Streaming helps when an agent processes each result downstream. If it fetches context records for sequential evaluation, it can start on the first record while execution continues on the rest. Streaming lowers wall-clock time from query start to the first useful result, but slightly increases total receipt time because each record carries framing overhead.
LaserData uses the same event delivery mechanism for streaming queries and subscriptions. State updates arrive with the same framing as streamed query results. This is deliberate: the agent SDK handles requested data and pushed real-time events through one callback interface, so agent code need not distinguish between them.
Where this model is and is not designed to help
This execution model targets agent decision-loop patterns: session-scoped context fetches, recency-ordered reads, and small result sets that repeat the same query shape. It is not intended for arbitrary analytics over large data sets, multi-way joins with complex predicates across unrelated entity types, or full-text search across large document collections.
If an agent explores its full history for patterns across hundreds of sessions, LaserData is not the right query engine for that workload. We are not saying this model handles every query shape; we are saying it is built for short, repeated, predictable queries. Under that assumption, the optimization passes compound into consistently low latency. Without it, those optimizations do not apply and execution overhead becomes visible.