Elastic Synthetics and APM together give you a powerful lens into how actual users experience your applications, not just how your application thinks it’s performing internally.
Let’s watch a real user journey, or at least, a simulated one that mimics it precisely.
Imagine a user wants to buy a book on an e-commerce site. Their journey might look like this:
- Landing Page: User arrives at
https://example-bookstore.com/. - Search: User types "Elasticsearch" into the search bar and hits enter.
- Search Results: User sees a list of books, hopefully including "The Logstash Handbook."
- Product Page: User clicks on "The Logstash Handbook" to view details.
- Add to Cart: User clicks "Add to Cart."
- Checkout: User proceeds to checkout.
Elastic Synthetics can simulate this exact sequence of steps from various global locations. It’s like having a robot user clicking through your site, reporting back on every step.
Here’s a simplified Synthetics monitor configuration (in YAML) that simulates the search and product page view:
name: Bookstore - Search and View Book
schedule: '@every 5m'
enabled: true
type: browser
locations:
- Frankfurt
- New York
steps:
- script: >
const { chromium } = require('playwright');
const browser = await chromium.launch();
const page = await browser.newPage();
// Step 1: Navigate to homepage
await page.goto('https://example-bookstore.com/');
console.log('Navigated to homepage');
// Step 2: Perform search
await page.fill('input[name="q"]', 'Elasticsearch');
await page.press('input[name="q"]', 'Enter');
console.log('Searched for "Elasticsearch"');
// Wait for search results to load (e.g., a specific element)
await page.waitForSelector('a:has-text("The Logstash Handbook")');
console.log('Search results loaded');
// Step 3: Click on the book
await page.click('a:has-text("The Logstash Handbook")');
console.log('Clicked on "The Logstash Handbook"');
// Wait for product page to load
await page.waitForSelector('h1:has-text("The Logstash Handbook")');
console.log('Product page loaded');
await browser.close();
This monitor runs every 5 minutes from Frankfurt and New York. If any step fails (e.g., the search input isn’t found, the book isn’t in the results, or the product page doesn’t load within a timeout), the Synthetics monitor will report an error.
Now, where APM comes in is by providing the internal view of what’s happening on your servers when these user actions occur. When a Synthetics monitor hits your application, it generates APM trace data. This data shows the breakdown of time spent in your backend services, databases, and external API calls.
For instance, when the Synthetics monitor performs the search, it triggers a request to your bookstore-search-service. APM will show you:
- The latency of the HTTP request to
bookstore-search-service. - The time spent within
bookstore-search-serviceitself. - If
bookstore-search-servicequeries a database (e.g., Elasticsearch for book titles), APM will show the query time. - If there are other downstream services involved, APM traces them too.
By correlating Synthetics failures with APM traces, you can pinpoint the root cause. A Synthetics monitor failing to find "The Logstash Handbook" might correlate with APM showing slow response times from your bookstore-search-service or an increase in errors within that service.
The power comes from the direct link: a Synthetics "transaction" is a user journey, and an APM "trace" is the backend execution of a part of that journey. You can even configure Synthetics monitors to tag their requests with specific identifiers that propagate to APM, allowing you to filter APM traces by a specific Synthetics journey. For example, you can add a custom header like X-Synthetics-Monitor: bookstore-search-view to the HTTP requests made by your Synthetics browser monitor. Then, in Kibana’s APM UI, you can filter traces where http.request.headers."x-synthetics-monitor" : "bookstore-search-view".
This allows you to ask questions like: "What is the average latency of my search service specifically when it’s being hit by the Frankfurt Synthetics monitor?" or "Are there any errors in my product service only when users are coming from the New York Synthetics journey?"
The most surprising truth is that Synthetics monitors, while appearing to be simple endpoint checks, can be configured to perform complex, multi-step interactions that precisely mirror sophisticated user workflows. They don’t just check if a page loads; they check if the entire sequence of actions a user would take to achieve a goal is successful and performant. This is crucial because a single page might load fine, but a broken interaction flow can render the entire application unusable for a specific user task.
The next logical step is to start chaining these journeys together. You can create a Synthetics monitor for the entire "purchase a book" flow, which implicitly includes the search and view steps. This allows you to monitor the end-to-end experience of your most critical user paths.